#include <Iguana/Framework/interface/IgModuleCache.h>
Public Types | |
typedef ModuleList::const_iterator | Iterator |
Iterator over IgModule objects in this cache. | |
Public Member Functions | |
Iterator | begin (void) const |
Return an iterator to the first Module in the cache. | |
lat::Filename | directory (void) const |
Return the module cache directory name. | |
Iterator | end (void) const |
Return an iterator one past the last Module in the cache. | |
IgModuleCache (IgPluginManager *manager, const lat::Filename &directory) | |
Initialise a module cache in directory. | |
IgPluginManager * | manager (void) const |
void | refresh (void) |
Refresh the module cache. | |
~IgModuleCache (void) | |
Destroy the module cache. | |
Protected Member Functions | |
void | load (void) |
Load the module cache file ".cache". | |
void | notify (void) |
Update m_modules from the current state of the cache (m_cache). | |
void | rebuild (void) |
Rebuild the cache comparing it to the actual directory contents. | |
void | update (void) |
Update the ".cache" file on the disk if it is writable. | |
Private Types | |
enum | CacheStatus { CACHE_MISSING = 1, CACHE_OLD = 2, CACHE_VALID = 3 } |
Different cache states. More... | |
typedef ModuleList::iterator | ModuleIterator |
Iterator over module registations. | |
typedef std::list< IgModule * > | ModuleList |
Module registrations (each of which maintains its list of modules). | |
Private Member Functions | |
bool | parse (const lat::Filename &filename, IgModuleDescriptor *root=0) |
Parse a module cache file (".cache" or one of the "*.reg" files). | |
void | reconstruct (IgModuleDescriptor *info) |
Validate and reconstruct descriptor proxies from info. | |
CacheStatus | scanModules (ModuleList &cache) |
Actually scan the module directory, compare it with the current m_cache, and build a new cache that reflects the changes. | |
void | write (std::ostream &s, IgModuleDescriptor *doc, int level=0) |
Dump the module descriptor doc and all it's children into the stream s. | |
Static Private Member Functions | |
static IgModuleDescriptor * | makeBad (const std::string &file, const std::string &time) |
Construct a module descriptor for a bad file with timestamp time. | |
Private Attributes | |
ModuleList | m_cache |
lat::Filename | m_directory |
IgPluginManager * | m_manager |
ModuleList | m_modules |
ParseContext | m_parse |
CacheContext | m_state |
Static Private Attributes | |
static const char | s_cacheFile [] = ".iglets" |
static const char | s_cacheTag [] = "cache" |
static const char | s_fileTag [] |
static const char | s_moduleTag [] |
Friends | |
struct | CacheContext |
class | FileByName |
struct | ParseContext |
Classes | |
struct | CacheContext |
Flags that describe the current cache status. More... | |
class | FileByName |
struct | ParseContext |
Structure used as temporary storage and result by parse() and reconstruct(). More... |
The IgPluginManager automatically instantiates a IgModuleCache for every module registration directory. The purpose of this class is to maintain an automatically updated cache about all the modules in the directory, including all the plug-ins registered in those modules. The cache object automatically refreshes the cache with respect to the on-disk registrations when it is created. Clients can also force an update by calling refresh(); note however that calling it on already-loaded modules whose library has been updated while the program is running is not a good idea.
The cache maintains information about all the registrations in the directory, including the time-stamp of each file. The cache is updated if the file time stamp is different from what it was when the data was cached. The cache also records time-stamps for bad files: files the cache does not understand or files that describe modules that fail to load for some reason. Such files are ignored until the on-disk file time stamp changes.
The IgModuleCache updates the on-disk cache automatically if it can, i.e. if it has write permissions on the directory. It never modifies the original registration files. If the cache file cannot be written, the errors are silently ignored and class proceeds with just the information in memory; the canonical data it maintains is the part that is in memory, the data on disk is merely an optimisation that avoids having to query all the modules all the time.
Note that if the cache cannot be written but needs to be updated, there is a performance penalty because the client programs will continuously refresh their caches. Thus when new modules are installed, it is important to refresh the cache before the directories are frozen.
The cache data is maintained in string form as IgModuleDescriptor objects. The IgModuleCache automatically creates IgModule objects as needed. When restoring a cache the information is passed as IgModuleDescriptor to the IgModule objects, which passes it to the IgPluginManager, which passes it to the IgPluginFactory categories as necessary. When writing the the IgModule objects are queried for their caches of the IgPluginInfo items registered with them, to produce IgModuleDescriptors for output.
Definition at line 68 of file IgModuleCache.h.
typedef ModuleList::const_iterator IgModuleCache::Iterator |
typedef ModuleList::iterator IgModuleCache::ModuleIterator [private] |
typedef std::list<IgModule *> IgModuleCache::ModuleList [private] |
Module registrations (each of which maintains its list of modules).
Definition at line 71 of file IgModuleCache.h.
enum IgModuleCache::CacheStatus [private] |
Different cache states.
The progression goes from first to last.
Definition at line 109 of file IgModuleCache.h.
00109 { 00110 CACHE_MISSING = 1, //< No cache 00111 CACHE_OLD = 2, //< Cache exists but is outdated 00112 CACHE_VALID = 3 //< Cache exists and is up-to-date 00113 };
IgModuleCache::IgModuleCache | ( | IgPluginManager * | manager, | |
const lat::Filename & | directory | |||
) |
Initialise a module cache in directory.
Initialises the cache to clear state and then invokes refresh() to rebuild; this causes for instance Module objects to be created.
Definition at line 103 of file IgModuleCache.cc.
References IgModuleCache::CacheContext::added, ASSERT, CACHE_MISSING, IgModuleCache::CacheContext::changed, lat::Filename::empty(), m_directory, m_parse, m_state, IgModuleCache::ParseContext::module, refresh(), IgModuleCache::CacheContext::removed, IgModuleCache::CacheContext::skipped, and IgModuleCache::CacheContext::status.
00104 : m_manager (manager), 00105 m_directory (directory.asDirectory ()) 00106 { 00107 ASSERT (! m_directory.empty ()); 00108 00109 m_state.status = CACHE_MISSING; 00110 m_state.added = m_state.removed 00111 = m_state.changed 00112 = m_state.skipped 00113 = false; 00114 00115 m_parse.module = 0; 00116 refresh (); 00117 }
IgModuleCache::~IgModuleCache | ( | void | ) |
Destroy the module cache.
Destroys all modules owned by the cache.
Definition at line 120 of file IgModuleCache.cc.
References ASSERT, lat::Filename::empty(), lat::indent(), LFplugin_manager, LOG, m, m_cache, m_directory, GsfMatrixTools::trace(), and lat::undent().
00121 { 00122 LOG (0, trace, LFplugin_manager, 00123 "destroying module cache for `" << m_directory << "'\n" << lat::indent); 00124 ASSERT (! m_directory.empty ()); 00125 for (ModuleIterator m = m_cache.begin (); m != m_cache.end (); ++m) 00126 delete *m; 00127 00128 LOG (0, trace, LFplugin_manager, lat::undent); 00129 }
IgModuleCache::Iterator IgModuleCache::begin | ( | void | ) | const |
Return an iterator to the first Module in the cache.
Definition at line 138 of file IgModuleCache.cc.
References m_modules.
00139 { return m_modules.begin (); }
lat::Filename IgModuleCache::directory | ( | void | ) | const |
Return the module cache directory name.
Definition at line 133 of file IgModuleCache.cc.
References m_directory.
Referenced by IgDirectoryByName::operator()().
00134 { return m_directory; }
IgModuleCache::Iterator IgModuleCache::end | ( | void | ) | const |
Return an iterator one past the last Module in the cache.
Definition at line 143 of file IgModuleCache.cc.
References m_modules.
Referenced by scanModules().
00144 { return m_modules.end (); }
Load the module cache file ".cache".
Attempts to load and rebuild the cache from the file. The cache is first set to CACHE_MISSING status and all m_state flags are cleared. If the file exists and can be parsed and reconstructed successfully, m_cache is set to the IgModule list and the cache status is set to CACHE_OLD. Otherwise m_cache is left untouched.
Definition at line 303 of file IgModuleCache.cc.
References IgModuleCache::CacheContext::added, CACHE_MISSING, CACHE_OLD, IgModuleCache::CacheContext::changed, lat::indent(), LFplugin_manager, LOG, m, m_cache, m_directory, m_parse, m_state, parse(), IgModuleCache::CacheContext::removed, IgModuleCache::ParseContext::result, s_cacheFile, IgModuleCache::CacheContext::skipped, IgModuleCache::CacheContext::status, GsfMatrixTools::trace(), and lat::undent().
Referenced by refresh().
00304 { 00305 LOG (0, trace, LFplugin_manager, "loading cache " 00306 << lat::Filename (m_directory, s_cacheFile) << '\n' << lat::indent); 00307 00308 m_state.status = CACHE_MISSING; 00309 m_state.added = m_state.removed 00310 = m_state.changed 00311 = m_state.skipped 00312 = false; 00313 00314 if (parse (s_cacheFile)) 00315 { 00316 m_state.status = CACHE_OLD; 00317 00318 // Clear the cache before adding to it (in case we already 00319 // have something, i.e. refresh() was already invoked). 00320 for (ModuleIterator m = m_cache.begin (); m != m_cache.end (); ++m) 00321 delete *m; 00322 00323 m_cache.clear (); 00324 m_cache.splice (m_cache.end (), m_parse.result); 00325 } 00326 00327 LOG (0, trace, LFplugin_manager, lat::undent << "done\n"); 00328 }
IgModuleDescriptor * IgModuleCache::makeBad | ( | const std::string & | file, | |
const std::string & | time | |||
) | [static, private] |
Construct a module descriptor for a bad file with timestamp time.
Definition at line 332 of file IgModuleCache.cc.
References IgPluginManager::ErrorBadCacheFile, IgPluginManager::feedback(), IgPluginManager::get(), s_cacheTag, and IgModule::tag().
00333 { 00334 IgPluginManager::get ()->feedback (IgPluginManager::ErrorBadCacheFile, file); 00335 IgModuleDescriptor *top = new IgModuleDescriptor (0, s_cacheTag); 00336 new IgModuleDescriptor (top, IgModule::tag (), file, time, "bad"); 00337 return top; 00338 }
IgPluginManager* IgModuleCache::manager | ( | void | ) | const |
Update m_modules from the current state of the cache (m_cache).
Definition at line 509 of file IgModuleCache.cc.
References lat::indent(), LFplugin_manager, LOG, m, m_cache, m_modules, GsfMatrixTools::trace(), and lat::undent().
Referenced by refresh().
00510 { 00511 LOG (0, trace, LFplugin_manager, "collecting modules\n" << lat::indent); 00512 for (ModuleIterator m = m_cache.begin (); m != m_cache.end (); ++m) 00513 if (! (*m)->bad ()) m_modules.push_back (*m); 00514 LOG (0, trace, LFplugin_manager, lat::undent); 00515 }
bool IgModuleCache::parse | ( | const lat::Filename & | file, | |
IgModuleDescriptor * | root = 0 | |||
) | [private] |
Parse a module cache file (".cache" or one of the "*.reg" files).
This both reads the file and reconstructs its contents as children of root; the descriptor tree is destroyed before the method returns. If reading in ".cache", root should be null, if reading in a single registration it should be contain the initial cache structure, otherwise reconstruct will fail. The reconstructed cache will be put into m_parse.result. Returns true
if the cache was successfully read and reconstructed, false
otherwise.
Definition at line 167 of file IgModuleCache.cc.
References IgModuleDescriptor::addToken(), ASSERT, IgModuleDescriptor::child(), IgModuleDescriptor::children(), decode(), doc, e, error, IgPluginManager::ErrorBadCacheFile, HLT_VtxMuL3::errors, lat::Error::explain(), f, IgPluginManager::feedback(), EgammaValidation_cff::filename, level, LFplugin_manager, LOG, m, m_directory, m_manager, m_parse, IgModuleCache::ParseContext::module, offset, IgPluginManager::Other, reconstruct(), IgModuleCache::ParseContext::result, IgModuleDescriptor::tokens(), and GsfMatrixTools::trace().
Referenced by load().
00168 { 00169 // FIXME: Use platform independent facilities for all file stuff (actually, registry) 00170 struct stat statbuf; 00171 lat::Filename filename (m_directory, file); 00172 bool errors = false; 00173 IgModuleDescriptor *regdata = root; 00174 00175 if (::stat (filename, &statbuf) == -1) 00176 { 00177 delete regdata; 00178 return true; 00179 } 00180 00181 LOG (0, trace, LFplugin_manager, "parsing file: " << file << "\n"); 00182 00183 ASSERT (m_parse.result.empty ()); 00184 ASSERT (! m_parse.module); 00185 00186 // Parse the registry file 00187 try { 00188 // FIXME: use an object so we don't need to fclose() it. 00189 FILE *f = fopen (filename, "r"); 00190 if (! f) 00191 throw IgPluginError (new IgPluginParserError ("can't read the file")); 00192 00193 typedef std::vector<IgModuleDescriptor *> ContextStack; 00194 ContextStack stack; 00195 int offset = 0; 00196 int ch; 00197 00198 // Bias the stack in case we were give a root preamble. In 00199 // that case we simply descend as far as we can into the first 00200 // children of the preamble, and insert parse results there. 00201 // `regdata' is assinged 00202 while (root) 00203 { 00204 ++offset; 00205 stack.push_back (root); 00206 root = root->children () ? root->child (0) : 0; 00207 } 00208 00209 // Process the file 00210 do { 00211 std::string token; 00212 int level = offset; 00213 00214 while ((ch = fgetc (f)) != EOF && ch == ' ') 00215 ++level; 00216 00217 if (ch == EOF) 00218 break; 00219 00220 if (level == 0 && regdata) 00221 { 00222 fclose (f); 00223 throw IgPluginError (new IgPluginParserError ("duplicate top level line")); 00224 } 00225 00226 stack.resize (level+1); 00227 IgModuleDescriptor *doc 00228 = new IgModuleDescriptor (level ? stack [level-1] : 0); 00229 stack [level] = doc; 00230 if (level == 0) 00231 regdata = doc; 00232 00233 for ( ; ch != EOF; ch = fgetc (f)) 00234 if (ch == '\n') 00235 { 00236 if (! token.empty ()) 00237 doc->addToken (decode (token)); 00238 00239 if (doc->tokens () == 0) 00240 { 00241 fclose (f); 00242 throw IgPluginError (new IgPluginParserError ("empty line")); 00243 } 00244 00245 break; 00246 } 00247 else if (ch == ' ') 00248 { 00249 if (! token.empty ()) 00250 doc->addToken (decode (token)); 00251 token = ""; 00252 } 00253 else 00254 token += ch; 00255 } while (ch != EOF); 00256 00257 fclose (f); 00258 reconstruct (regdata); 00259 00260 ASSERT (! m_parse.module); 00261 } catch (lat::Error &e) { 00262 m_manager->feedback (IgPluginManager::ErrorBadCacheFile, file, &e); 00263 00264 // FIXME: Notify owner 00265 LOG (0, error, LFplugin_manager, 00266 file << ": error, file ignored (" << e.explain() << ")\n"); 00267 00268 errors = true; 00269 } catch (...) { 00270 m_manager->feedback (IgPluginManager::Other, file); 00271 00272 // FIXME: Notify owner 00273 LOG (0, error, LFplugin_manager, 00274 file << ": unknown error, file ignored\n"); 00275 00276 errors = true; 00277 } 00278 00279 delete regdata; 00280 00281 if (errors) 00282 { 00283 delete m_parse.module; 00284 m_parse.module = 0; 00285 00286 for (ModuleIterator m = m_parse.result.begin (); 00287 m != m_parse.result.end (); ++m) 00288 delete *m; 00289 00290 m_parse.result.clear (); 00291 } 00292 00293 return !errors; 00294 }
Rebuild the cache comparing it to the actual directory contents.
Assumes any existing cache is already loaded. Scans the directory contents and compares with the cache, updating it to the new state of things. Updates m_state to reflect what happened.
Definition at line 483 of file IgModuleCache.cc.
References IgModuleCache::CacheContext::added, IgModuleCache::CacheContext::changed, lat::indent(), LFplugin_manager, LOG, m, m_cache, m_directory, m_state, IgModuleCache::CacheContext::removed, scanModules(), IgModuleCache::CacheContext::skipped, IgModuleCache::CacheContext::status, GsfMatrixTools::trace(), and lat::undent().
Referenced by refresh().
00484 { 00485 LOG (0, trace, LFplugin_manager, 00486 "rebuilding cache in `" << m_directory << "'\n" << lat::indent); 00487 00488 // Build a new cache and stealing bits from the old one as the new 00489 // one is rebuilt. Then replace the cache with the new one and 00490 // delete whatever was left over from the old cache (creating the 00491 // new one may steal bits of the old). 00492 ModuleList cache; 00493 m_state.status = scanModules (cache); 00494 m_cache.swap (cache); 00495 for (ModuleIterator m = cache.begin (); m != cache.end (); ++m) 00496 delete *m; 00497 00498 LOG (0, trace, LFplugin_manager, 00499 lat::undent << "done (" << (int) m_state.status 00500 << ", added = " << m_state.added 00501 << ", removed = " << m_state.removed 00502 << ", changed = " << m_state.changed 00503 << ", skipped = " << m_state.skipped 00504 << ")\n"); 00505 }
void IgModuleCache::reconstruct | ( | IgModuleDescriptor * | info | ) | [private] |
Validate and reconstruct descriptor proxies from info.
Definition at line 589 of file IgModuleCache.cc.
References ASSERT, IgModuleDescriptor::child(), IgModuleDescriptor::children(), i, LFplugin_manager, LOG, m_directory, m_manager, m_parse, IgModuleCache::ParseContext::module, IgModuleDescriptor::parent(), IgModule::restore(), IgModuleCache::ParseContext::result, s_cacheTag, IgModule::tag(), IgModuleDescriptor::token(), IgModuleDescriptor::tokens(), and GsfMatrixTools::trace().
Referenced by parse(), and scanModules().
00590 { 00591 // Protect against random junk, e.g. empty files 00592 if (! info || ! info->tokens ()) 00593 throw IgPluginError (new IgPluginParserError ("empty descriptor")); 00594 00595 // Make sure the root is either a cache... 00596 if (info->token (0) == s_cacheTag) 00597 { 00598 if (info->tokens () != 1) 00599 throw IgPluginError (new IgPluginParserError 00600 ("`cache' does not take arguments")); 00601 else if (info->parent ()) 00602 throw IgPluginError (new IgPluginParserError 00603 ("`cache' must be at the root")); 00604 00605 for (unsigned i = 0; i < info->children (); ++i) 00606 reconstruct (info->child (i)); 00607 00608 ASSERT (! m_parse.module); 00609 } 00610 // ... or a module itself 00611 else if (info->token (0) == IgModule::tag ()) 00612 { 00613 if (info->tokens () != 4) 00614 throw IgPluginError (new IgPluginParserError 00615 ("`module' must have three arguments")); 00616 if (! info->parent () || info->parent ()->token (0) != s_cacheTag) 00617 throw IgPluginError (new IgPluginParserError 00618 ("`module' must be under `cache'")); 00619 if (info->token (3) != "good" && info->token (3) != "bad") 00620 throw IgPluginError (new IgPluginParserError 00621 ("`module' last argument must be" 00622 " 'good' or 'bad'")); 00623 00624 ASSERT (! m_parse.module); 00625 m_parse.module = new IgModule (m_manager, 00626 lat::Filename (m_directory, info->token (1)), 00627 info->token (2), 00628 info->token (3)); 00629 00630 for (unsigned i = 0; i < info->children (); ++i) 00631 reconstruct (info->child (i)); 00632 00633 ASSERT (m_parse.module); 00634 m_parse.result.push_back (m_parse.module); 00635 m_parse.module = 0; 00636 } 00637 // ... or junk we don't understand 00638 else 00639 { 00640 if (! m_parse.module) 00641 throw IgPluginError (new IgPluginParserError 00642 (info->token (0) + " unexpected")); 00643 00644 if (info->tokens () >= 2) 00645 LOG (0, trace, LFplugin_manager, "processing " 00646 << info->token(0) << ' ' << info->token(1) << '\n'); 00647 00648 m_parse.module->restore (info); 00649 } 00650 }
Refresh the module cache.
This causes the old ".cache" file to be loaded and to be compared with the current state of the directory. If there are any differences, a new cache will be written out.
Definition at line 150 of file IgModuleCache.cc.
References load(), notify(), rebuild(), and update().
Referenced by IgModuleCache().
IgModuleCache::CacheStatus IgModuleCache::scanModules | ( | ModuleList & | cache | ) | [private] |
Actually scan the module directory, compare it with the current m_cache, and build a new cache that reflects the changes.
Returns a cache status code to reflect the new state.
Definition at line 344 of file IgModuleCache.cc.
References IgModuleCache::CacheContext::added, ASSERT, CACHE_MISSING, CACHE_OLD, CACHE_VALID, IgModuleCache::CacheContext::changed, e, end(), error, IgPluginManager::ErrorBadModule, lat::Error::explain(), IgPluginManager::feedback(), file, FileByName, EgammaValidation_cff::filename, lat::indent(), LFplugin_manager, LOG, m, m_cache, m_directory, m_manager, m_parse, m_state, edm::match(), IgModuleCache::ParseContext::module, reconstruct(), IgModuleCache::CacheContext::removed, HLT_VtxMuL3::result, IgModuleCache::ParseContext::result, s_cacheFile, s_cacheTag, IgModuleCache::CacheContext::skipped, StDecayID::status, IgModule::tag(), GsfMatrixTools::trace(), and lat::undent().
Referenced by rebuild().
00345 { 00346 LOG (0, trace, LFplugin_manager, 00347 "scanning `" << m_directory << "'\n" << lat::indent); 00348 00349 CacheStatus result = CACHE_MISSING; 00350 lat::DirIterator file (m_directory); 00351 lat::DirIterator end; 00352 00353 ASSERT (cache.empty ()); 00354 for (; file != end; ++file) 00355 { 00356 // Ignore the cache file. 00357 if (*file == s_cacheFile) 00358 continue; 00359 00360 // Check, read and validate the module definition file. 00361 // FIXME: Use platform-independent facilities! 00362 struct stat statbuf; 00363 lat::Filename filename (m_directory, *file); 00364 if (filename.extension () != "iglet") 00365 continue; 00366 00367 // Ignore files we cannot stat 00368 int status = stat (filename, &statbuf); 00369 if (status == -1) 00370 { 00371 LOG (0, error, LFplugin_manager, 00372 "stat() failed with error " << errno << ", ignoring `" 00373 << *file << "'\n"); 00374 m_state.skipped = true; 00375 continue; 00376 } 00377 00378 // Check whether the module reg fragment has changed by 00379 // comparing the file and cached timestamps. 00380 ModuleIterator match 00381 = std::find_if (m_cache.begin(), m_cache.end(), 00382 FileByName (*file)); 00383 00384 if (match == m_cache.end ()) 00385 { 00386 LOG (0, trace, LFplugin_manager, 00387 "==> new module definition `" << *file << "'\n"); 00388 m_state.added = true; 00389 } 00390 else if ((*match)->time () != (unsigned long) statbuf.st_mtime) 00391 { 00392 LOG (0, trace, LFplugin_manager, 00393 "==> modified module definition `" << *file << "' (file is " 00394 << statbuf.st_mtime << ", cached was " << (*match)->time () 00395 << ")\n"); 00396 m_state.changed = true; 00397 } 00398 else 00399 { 00400 // Copy the old cache to the new cache. This relies on 00401 // the knowledge that the old cache will be thrown away 00402 // and so it is ok to steal the entry from the old one to 00403 // the new one. 00404 LOG (0, trace, LFplugin_manager, 00405 "==> unchanged definition `" << *file << "'\n"); 00406 cache.splice (cache.end (), m_cache, match); 00407 continue; 00408 } 00409 00410 // Construct a fake registry document root for this file 00411 std::string time = lat::StringFormat ("%1").arg (statbuf.st_mtime); 00412 IgModuleDescriptor *top = new IgModuleDescriptor (0, s_cacheTag); 00413 new IgModuleDescriptor (top, IgModule::tag (), *file, time, "good"); 00414 ASSERT (m_parse.result.empty ()); 00415 ASSERT (! m_parse.module); 00416 reconstruct (top); 00417 ASSERT (! m_parse.module); 00418 00419 // Try loading the modules to check that they are well-formed: 00420 // ensure that each module loads and resolves the required 00421 // entry points. If this fails, mark the whole registration 00422 // file bad so that it will be ignored until the time-stamp 00423 // changes. This leaves the cache always in valid state, 00424 // remembering anything bad. 00425 ASSERT (m_parse.result.size () == 1); 00426 for (ModuleIterator m = m_parse.result.begin () ; m != m_parse.result.end (); ++m) 00427 try 00428 { 00429 (*m)->load (); // checks for entry points 00430 (*m)->query (); 00431 (*m)->unload (); 00432 } 00433 catch (lat::Error &e) 00434 { 00435 m_manager->feedback (IgPluginManager::ErrorBadModule, 00436 (*m)->libraryName (), &e); 00437 00438 // FIXME: Notify to owner 00439 LOG (0, error, LFplugin_manager, 00440 *file << ": bad module library `" 00441 << (*m)->libraryName () 00442 << "', module ignored\n (error was: " 00443 << e.explain () << ")\n"); 00444 m_state.skipped = true; 00445 (*m)->bad (true); 00446 break; 00447 } 00448 00449 // Transfer into cache. 00450 cache.splice (cache.end (), m_parse.result); 00451 } 00452 00453 // See if cache contains info on removed modules. 00454 for (ModuleIterator m = m_cache.begin (); m != m_cache.end (); ++m) 00455 if (std::find_if (cache.begin (), cache.end (), 00456 FileByName ((*m)->libraryName ().nondirectory ())) 00457 == cache.end ()) 00458 { 00459 LOG (0, trace, LFplugin_manager, 00460 "==> removed module `" << (*m)->libraryName () << "'\n"); 00461 m_state.removed = true; 00462 } 00463 00464 // Update status codes. Note that CACHE_VALID means .cache is 00465 // valid, CACHE_OLD means it needs updating. If directory was 00466 // empty, mark the cache valid so we don't try to create one. 00467 result = (m_state.added 00468 || m_state.removed 00469 || m_state.changed 00470 || m_state.skipped) 00471 ? CACHE_OLD : CACHE_VALID; 00472 00473 LOG (0, trace, LFplugin_manager, 00474 lat::undent << "done (" << (int) result << ")\n"); 00475 return result; 00476 }
Update the ".cache" file on the disk if it is writable.
Definition at line 538 of file IgModuleCache.cc.
References python::cmstools::all(), CACHE_VALID, data, error, file, EgammaValidation_cff::filename, lat::indent(), LFplugin_manager, LOG, m, m_cache, m_directory, m_state, s_cacheFile, s_cacheTag, IgModuleCache::CacheContext::status, GsfMatrixTools::trace(), lat::undent(), and write().
Referenced by refresh().
00539 { 00540 if (m_state.status == CACHE_VALID) 00541 return; 00542 00543 // Regenerate cache file from information we have in memory 00544 LOG (0, trace, LFplugin_manager, 00545 "updating cache in `" << m_directory << "'\n" << lat::indent); 00546 00547 // Build a descriptor tree and dump it out 00548 IgModuleDescriptor *all = new IgModuleDescriptor (0, s_cacheTag); 00549 for (ModuleIterator m = m_cache.begin (); m != m_cache.end (); ++m) 00550 (*m)->cache (all); 00551 00552 std::ostringstream buf; 00553 write (buf, all); 00554 delete all; 00555 00556 lat::Filename filename (m_directory, s_cacheFile); 00557 FILE *file = STDC::fopen (filename, "wb"); 00558 00559 if (! file) 00560 { 00561 LOG (0, error, LFplugin_manager, 00562 filename << ": error " << errno << ", unable to open the cache" 00563 " for writing -- cache not updated\n" << lat::undent); 00564 return; 00565 } 00566 00567 std::string data (buf.str ()); 00568 if (STDC::fwrite (data.c_str (), 1, data.size (), file) != data.size ()) 00569 { 00570 LOG (0, error, LFplugin_manager, 00571 filename << ": error " << errno << " while writing cache out" 00572 " -- forcing file truncation\n"); 00573 00574 file = STDC::freopen (filename, "wb", file); 00575 } 00576 else 00577 m_state.status = CACHE_VALID; 00578 00579 STDC::fclose (file); 00580 00581 LOG (0, trace, LFplugin_manager, lat::undent << "done\n"); 00582 }
void IgModuleCache::write | ( | std::ostream & | s, | |
IgModuleDescriptor * | doc, | |||
int | level = 0 | |||
) | [private] |
Dump the module descriptor doc and all it's children into the stream s.
Output should happen at nesting level; omit this argument on the first call, it is meant to be used only in the internal implementation.
Definition at line 525 of file IgModuleCache.cc.
References IgModuleDescriptor::child(), IgModuleDescriptor::children(), encode(), lat::endl(), i, IgModuleDescriptor::token(), and IgModuleDescriptor::tokens().
Referenced by update().
00526 { 00527 s << std::string (level, ' ') << encode (doc->token (0)); 00528 for (unsigned i = 1; i < doc->tokens (); ++i) 00529 s << ' ' << encode (doc->token (i)); 00530 s << std::endl; 00531 00532 for (unsigned i = 0; i < doc->children (); ++i) 00533 write (s, doc->child (i), level+1); 00534 }
friend struct CacheContext [friend] |
Definition at line 102 of file IgModuleCache.h.
friend class FileByName [friend] |
friend struct ParseContext [friend] |
Definition at line 105 of file IgModuleCache.h.
ModuleList IgModuleCache::m_cache [private] |
Definition at line 144 of file IgModuleCache.h.
Referenced by load(), notify(), rebuild(), scanModules(), update(), and ~IgModuleCache().
lat::Filename IgModuleCache::m_directory [private] |
Definition at line 143 of file IgModuleCache.h.
Referenced by directory(), IgModuleCache(), load(), parse(), rebuild(), reconstruct(), scanModules(), update(), and ~IgModuleCache().
IgPluginManager* IgModuleCache::m_manager [private] |
Definition at line 142 of file IgModuleCache.h.
Referenced by parse(), reconstruct(), and scanModules().
ModuleList IgModuleCache::m_modules [private] |
ParseContext IgModuleCache::m_parse [private] |
Definition at line 146 of file IgModuleCache.h.
Referenced by IgModuleCache(), load(), parse(), reconstruct(), and scanModules().
CacheContext IgModuleCache::m_state [private] |
Definition at line 145 of file IgModuleCache.h.
Referenced by IgModuleCache(), load(), rebuild(), scanModules(), and update().
const char IgModuleCache::s_cacheFile = ".iglets" [static, private] |
const char IgModuleCache::s_cacheTag = "cache" [static, private] |
Definition at line 150 of file IgModuleCache.h.
Referenced by makeBad(), reconstruct(), scanModules(), and update().
const char IgModuleCache::s_fileTag[] [static, private] |
Definition at line 151 of file IgModuleCache.h.
const char IgModuleCache::s_moduleTag[] [static, private] |
Definition at line 152 of file IgModuleCache.h.