root/juggler/tags/1.0.5/Kernel/vjConfigManager.cpp

Revision 7539, 8.4 kB (checked in by anonymous, 7 years ago)

This commit was manufactured by cvs2svn to create tag
'RELENG_1_0_5_RELEASE'.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*************** <auto-copyright.pl BEGIN do not edit this line> **************
2  *
3  * VR Juggler is (C) Copyright 1998, 1999, 2000 by Iowa State University
4  *
5  * Original Authors:
6  *   Allen Bierbaum, Christopher Just,
7  *   Patrick Hartling, Kevin Meinert,
8  *   Carolina Cruz-Neira, Albert Baker
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public
21  * License along with this library; if not, write to the
22  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23  * Boston, MA 02111-1307, USA.
24  *
25  * -----------------------------------------------------------------
26  * File:          $RCSfile$
27  * Date modified: $Date$
28  * Version:       $Revision$
29  * -----------------------------------------------------------------
30  *
31  *************** <auto-copyright.pl END do not edit this line> ***************/
32
33 #include <vjConfig.h>
34 #include <Kernel/vjConfigManager.h>
35 #include <Config/vjConfigChunk.h>
36 #include <Config/vjChunkFactory.h>
37 #include <Kernel/vjDependencyManager.h>
38 #include <Kernel/vjDebug.h>
39 #include <stdlib.h>
40
41 /*
42 vjConfigManager* vjConfigManager::_instance = NULL;
43 vjMutex  vjConfigManager::_inst_lock;
44 */
45 vjSingletonImp(vjConfigManager);
46
47 //: Do we need to check the pending list
48 //! CONCURRENCY: concurrent
49 // The routine counts the number of pending chunks
50 // each time it is called.
51 // if it goes pending_repeat_limit calls without
52 // changing size, then it returns false until mLastPendingSize changes
53 bool vjConfigManager::pendingNeedsChecked()
54 {
55    const int pending_repeat_limit = 1;    // Must be one or greater.  1 means only allow one time of no changes
56    int cur_pending_size = 0;
57    bool ret_val = false;
58
59    mPendingCountMutex.acquire();
60    {
61       cur_pending_size = mPendingConfig.size();
62       if(cur_pending_size != mLastPendingSize)
63       {
64          ret_val = true;                           // Flag it for a check
65          mPendingCheckCount=0;                     // Reset the counter
66          mLastPendingSize = cur_pending_size;      // Keep track of size
67       }
68       else if(mPendingCheckCount < pending_repeat_limit)     // allowed in at least once [1...pending_repeat_limit]
69       {
70          mPendingCheckCount++;   // Increment it
71
72          if(mPendingCheckCount < pending_repeat_limit)
73          {
74             ret_val = true;        // Repeats still allowed
75          }
76          else
77          {
78             vjDEBUG(vjDBG_ALL, vjDBG_CRITICAL_LVL)
79                 << "vjConfigManager::pendingNeedsChecked: Pending list is now\n"
80                 << vjDEBUG_FLUSH;
81             vjDEBUG_NEXT(vjDBG_ALL, vjDBG_CRITICAL_LVL)
82                 << clrOutNORM(clrGREEN,"STALE: ")
83                 << cur_pending_size << " items still in pending\n"
84                 << vjDEBUG_FLUSH;
85             vjDEBUG_NEXT(vjDBG_ALL, vjDBG_CRITICAL_LVL)
86                 << "NOTE: These items have been specified in configuration,\n"
87                 << vjDEBUG_FLUSH;
88             vjDEBUG_NEXT(vjDBG_ALL, vjDBG_CRITICAL_LVL)
89                 << "      but have not been loaded.\n" << vjDEBUG_FLUSH;
90             vjDEBUG_NEXT(vjDBG_ALL, vjDBG_CRITICAL_LVL)
91                 << "      This may be an error in the configuration OR\n"
92                 << vjDEBUG_FLUSH;
93             vjDEBUG_NEXT(vjDBG_ALL, vjDBG_CRITICAL_LVL)
94                 << "      it may be waiting for more configuration information.\n"
95                 << vjDEBUG_FLUSH;
96 //            vjDEBUG(vjDBG_ALL, vjDBG_CRITICAL_LVL) << vjDEBUG_FLUSH;
97
98             lockPending();
99             debugDumpPending(vjDBG_CRITICAL_LVL); // Output the stale pending list
100             unlockPending();
101
102             ret_val = false;
103          }
104       }
105       else
106       {
107          ret_val = false;
108       }
109    }
110    mPendingCountMutex.release();
111
112    return ret_val;
113 }
114
115
116 // Add the given chunk db to the pending list as adds
117 void vjConfigManager::addChunkDB(vjConfigChunkDB* db)
118 {
119    vjASSERT(0 == mPendingLock.test());     // ASSERT: Make sure we don't already have it
120    lockPending();
121    {
122       vjPendingChunk pending;
123       pending.mType = vjPendingChunk::ADD;
124
125       for(std::vector<vjConfigChunk*>::iterator i=db->begin();i!=db->end();i++)
126       {
127          pending.mChunk = (*i);
128          mPendingConfig.push_back(pending);
129       }
130    }
131    unlockPending();
132
133    // Reset pending count
134    mPendingCountMutex.acquire();
135    mPendingCheckCount = 0;
136    mPendingCountMutex.release();
137
138 }
139
140 void vjConfigManager::removeChunkDB(vjConfigChunkDB* db)
141 {
142    vjASSERT(0 == mPendingLock.test());     // ASSERT: Make sure we don't already have it
143    lockPending();
144    {
145       vjPendingChunk pending;
146       pending.mType = vjPendingChunk::REMOVE;
147
148       for(std::vector<vjConfigChunk*>::iterator i=db->begin();i!=db->end();i++)
149       {
150          pending.mChunk = (*i);
151          mPendingConfig.push_back(pending);
152       }
153    }
154    unlockPending();
155
156    // Reset pending count
157    mPendingCountMutex.acquire();
158    mPendingCheckCount = 0;
159    mPendingCountMutex.release();
160
161 }
162
163 // Look for items in the active list that don't have their dependencies filled anymore
164 //
165 //! POST: Any chunks in active with dependencies not filled are added to the
166 //+       the pending list. (A remove and an add are added to the pending)
167 //! RETURNS: The number of lost dependencies found
168 int vjConfigManager::scanForLostDependencies()
169 {
170    vjASSERT(0 == mActiveLock.test());        // We can't hold the lock upon entry
171
172    vjDEBUG_BEGIN(vjDBG_ALL,1) << "vjConfigManager::scanForLostDependencies: Entered: \n" << vjDEBUG_FLUSH;
173
174    vjDependencyManager* dep_mgr = vjDependencyManager::instance();
175    std::vector<vjConfigChunk*> chunks;
176    int num_lost_deps(0);
177
178    // NOTE: can't hold this lock because the depSatisfied routines make use of the activeLock as well
179    // NOTE: Make the copy of the chunks so that we can iterate without fear of active changing
180    mActiveLock.acquire();
181       chunks = mActiveConfig.getChunks();   // Get a copy of the chunks
182    mActiveLock.release();
183
184    // Now test them
185    for(unsigned int i=0;i<chunks.size();i++)
186    {
187       if(!dep_mgr->depSatisfied(chunks[i]))      // We are not satisfied
188       {
189          vjDEBUG_NEXT(vjDBG_ALL,1) << chunks[i]->getProperty("name")
190                                    << " type: " << ((std::string)chunks[i]->getType()).c_str()
191                                    << " has lost dependencies.\n"
192                                    << vjDEBUG_FLUSH;
193
194          num_lost_deps++;              // Keep a count of the number lost deps found
195
196          // Add the pending removal
197          vjPendingChunk pending;
198          pending.mType = vjPendingChunk::REMOVE;
199          pending.mChunk = chunks[i];
200          addPending(pending);
201
202          // Add the pending re-addition
203          vjConfigChunk* copy_of_chunk;          // Need a copy so that the remove can delete the chunk
204          copy_of_chunk = new vjConfigChunk (*chunks[i]);
205          pending.mType = vjPendingChunk::ADD;
206          pending.mChunk = copy_of_chunk;
207          addPending(pending);                   // Add the add item
208       }
209    }
210
211    vjDEBUG_END(vjDBG_ALL,1) << "vjConfigManager::scanForLostDependencies: Exiting: \n" << vjDEBUG_FLUSH;
212
213    return num_lost_deps;
214 }
215
216
217 void vjConfigManager::debugDumpPending(int debug_level)
218 {
219    vjASSERT(1 == mPendingLock.test());
220    vjDEBUG(vjDBG_ALL,debug_level)
221          << clrSetNORM(clrGREEN)
222          << "---- Pending list: " << mPendingConfig.size() << " items ----\n"
223          << clrRESET << vjDEBUG_FLUSH;
224    std::list<vjConfigManager::vjPendingChunk>::iterator current, end;
225    current = getPendingBegin();
226    end = getPendingEnd();
227
228    while(current != end)
229    {
230       vjConfigChunk* cur_chunk = (*current).mChunk;
231
232       vjDEBUG_NEXT(vjDBG_ALL,debug_level) << cur_chunk->getProperty("name")
233                                         << " type: "
234                                         << ((std::string)cur_chunk->getType()).c_str()
235                                         << std::endl << vjDEBUG_FLUSH;
236       current++;
237    }
238    vjDEBUG_NEXT(vjDBG_ALL,debug_level)
239        << "----------------------------------\n" << vjDEBUG_FLUSH;
240 }
Note: See TracBrowser for help on using the browser.