CMS 3D CMS Logo

IgModule Class Reference

Module proxy. More...

#include <Iguana/Framework/interface/IgModule.h>

List of all members.

Public Types

typedef InfoList::const_iterator InfoIterator

Public Member Functions

void addInfo (IgPluginInfo *info, bool cache)
virtual void attach (void)
virtual bool attached (void)
void bad (bool value)
 Mark the module registration good or bad according to value.
bool bad (void) const
 Check if the module registration has been marked bad.
InfoIterator beginInfos (void) const
IgModuleDescriptorcacheRoot (void) const
virtual void detach (void)
void detachInfo (IgPluginInfo *info)
InfoIterator endInfos (void) const
 IgModule (IgPluginManager *manager, const lat::Filename &libraryName, const std::string &time, const std::string &flag)
const lat::FilenamelibraryName (void) const
virtual void load (void)
IgPluginManagermanager (void) const
virtual void query (void)
unsigned time (void) const
 Return the registration file time stamp.
virtual void unload (void)
virtual ~IgModule (void)

Static Public Member Functions

static IgModulebuiltin (void)

Protected Member Functions

virtual void cache (IgModuleDescriptor *to) const
 Dump the contents of the module registration into the cache to.
IgModuleCapEntry capabilityEntryPoint (void)
virtual bool checkEntryPoints (void) const
void clearCache (void)
lat::SharedLibrarylibrary (void) const
bool loaded (void) const
void makeCache (void)
IgModuleEntry moduleEntryPoint (void)
virtual void restore (IgModuleDescriptor *info)

Static Protected Member Functions

static const char * tag (void)

Private Types

typedef std::list< IgPluginInfo * > InfoList

Private Member Functions

 IgModule (const IgModule &)
IgModuleoperator= (const IgModule &)

Private Attributes

bool m_attached
bool m_bad
IgModuleDescriptorm_cache
IgModuleDefm_definition
InfoList m_infos
lat::SharedLibrarym_library
lat::Filename m_libraryName
IgPluginManagerm_manager
unsigned m_time

Static Private Attributes

static const char s_capEntryPoint [] = "IGUANA_CAPABILITIES"
static const char s_modEntryPoint [] = "IGUANA_MODULE"
static const char s_tag [] = "module"

Friends

class IgModuleCache


Detailed Description

Module proxy.

This class maintains the list of the capabilities provided by a plug-in module, but only in a generic manner. Custom plug-in factories provide access to specific information. The two are coordinated so that as new modules enter and leave the system the factory views are synchronised, and as new factories enter and leave, the information is cached and uncached automatically.

A IgModule exists for each module in an IgModuleCache regardless of whether the module library is presently loaded. The module is queried for the list of properties it provides (see IgModuleDef, DEFINE_IGUANA_MODULE, DEFINE_IGUANA_PLUGIN). IgModuleDirectory caches the information for later accesses without having to query the module. If the module changes, it us automatically queried again to update the cache.

IgModule can also treat the program itself as a module through the builtin() method. This allows dynamic loading to be bypassed as long as clients always use custom IgPluginManager factories and IgPluginLoader. Defining IGUANA_BUILTIN_PLUGINS preprocessor macro causes DEFINE_IGUANA_MODULE() and DEFINE_SEAL_PLUGIN() to a variant that automatically does so.

It is not safe to detach a module if there are any references remaining to it. This means there can be no live objects whose implementation for any part, including but not limited to virtual function tables, methods, template functions or static data, belong to the library detached. Note: this applies to any object created by the library, not just the plug-ins created by it!

For purposes of IgModuleCache the object remembers the time stamp of the module file when it was last examined, and whether it is good or bad. "Bad" means either that the file is corrupt in some way, for example the module could not be loaded.

Definition at line 69 of file IgModule.h.


Member Typedef Documentation

typedef InfoList::const_iterator IgModule::InfoIterator

Definition at line 73 of file IgModule.h.

typedef std::list<IgPluginInfo *> IgModule::InfoList [private]

Definition at line 71 of file IgModule.h.


Constructor & Destructor Documentation

IgModule::IgModule ( IgPluginManager manager,
const lat::Filename libraryName,
const std::string &  time,
const std::string &  flag 
)

Definition at line 43 of file IgModule.cc.

References ASSERT, LFplugin_manager, LOG, m_libraryName, makeCache(), and GsfMatrixTools::trace().

Referenced by builtin().

00047     : m_manager (manager),
00048       m_libraryName (libraryName),
00049       m_library (0),
00050       m_cache (0),
00051       m_time (strtoul (time.c_str (), 0, 10)),
00052       m_bad (flag != "good"),
00053       m_attached (libraryName.empty ()),
00054       m_definition (0)
00055 {
00056     ASSERT (flag == "good" || flag == "bad");
00057     ASSERT (! time.empty ());
00058     LOG (0, trace, LFplugin_manager,
00059          "constructing module for library `" << m_libraryName << "'\n");
00060     makeCache ();
00061 }

IgModule::~IgModule ( void   )  [virtual]

Definition at line 63 of file IgModule.cc.

References ASSERT, LFplugin_manager, LOG, m_cache, m_infos, m_library, m_libraryName, GsfMatrixTools::trace(), and unload().

00064 {
00065     LOG (0, trace, LFplugin_manager,
00066          "destroying module for library `" << m_libraryName << "'\n");
00067 
00068     unload ();
00069     ASSERT (! m_library);
00070 
00071     while (! m_infos.empty ())
00072         delete *m_infos.begin ();
00073 
00074     delete m_cache;
00075 }

IgModule::IgModule ( const IgModule  )  [private]


Member Function Documentation

void IgModule::addInfo ( IgPluginInfo info,
bool  cache 
)

Definition at line 203 of file IgModule.cc.

References IgPluginManager::addInfo(), IgPluginInfo::cache(), cacheRoot(), m_infos, and m_manager.

Referenced by IgPluginInfo::finish().

00204 {
00205     if (needCache)
00206         // This info isn't cached yet -- add it.
00207         info->cache (cacheRoot ());
00208 
00209     m_infos.push_back (info);
00210     m_manager->addInfo (info);
00211 }

void IgModule::attach ( void   )  [virtual]

Definition at line 313 of file IgModule.cc.

References ASSERT, IgModuleDef::attach(), IgModuleDef::bind(), empty, IgPluginManager::feedback(), lat::indent(), LFplugin_manager, libraryName(), LOG, m_attached, m_definition, m_libraryName, m_manager, moduleEntryPoint(), IgPluginManager::StatusAttaching, GsfMatrixTools::trace(), and lat::undent().

00314 {
00315     if (! m_attached && ! libraryName ().empty ())
00316     {
00317         ASSERT (! m_definition);
00318 
00319         LOG (0, trace, LFplugin_manager,
00320              "attaching module " << libraryName () << '\n' << lat::indent);
00321 
00322         // Capability-only modules don't have a normal entry; we
00323         // don't need a definition for them either.
00324         if (IgModuleEntry entry = moduleEntryPoint ())
00325         {
00326             m_definition = (*entry) ();
00327             ASSERT (m_definition);
00328 
00329             m_manager->feedback (IgPluginManager::StatusAttaching, m_libraryName);
00330             m_definition->bind (this);
00331             m_definition->attach ();
00332         }
00333 
00334         m_attached = true;
00335         LOG (0, trace, LFplugin_manager, lat::undent);
00336     }
00337 }

bool IgModule::attached ( void   )  [virtual]

Definition at line 422 of file IgModule.cc.

References m_attached.

00423 { return m_attached; }

void IgModule::bad ( bool  value  ) 

Mark the module registration good or bad according to value.

Setting the value to true resets the module contents.

Definition at line 94 of file IgModule.cc.

References clearCache(), and m_bad.

00095 { if ((m_bad = value)) clearCache (); }

bool IgModule::bad ( void   )  const

Check if the module registration has been marked bad.

Definition at line 88 of file IgModule.cc.

References m_bad.

Referenced by makeCache().

00089 { return m_bad; }

IgModule::InfoIterator IgModule::beginInfos ( void   )  const

Definition at line 195 of file IgModule.cc.

References m_infos.

00196 { return m_infos.begin (); }

IgModule * IgModule::builtin ( void   )  [static]

Definition at line 35 of file IgModule.cc.

References IgPluginManager::get(), and IgModule().

00036 {
00037     static IgModule *myself = new IgModule (IgPluginManager::get (),
00038                                             "" /* magic library name */,
00039                                             "0", "good");
00040     return myself;
00041 }

void IgModule::cache ( IgModuleDescriptor to  )  const [protected, virtual]

Dump the contents of the module registration into the cache to.

Definition at line 238 of file IgModule.cc.

References IgModuleDescriptor::dup(), and m_cache.

00239 {
00240     // Internal cache is already in sync (we update it every time a
00241     // new info item is created), so let base class do all the work.
00242     m_cache->dup (to);
00243 }

IgModuleDescriptor * IgModule::cacheRoot ( void   )  const

Definition at line 190 of file IgModule.cc.

References m_cache.

Referenced by addInfo().

00191 { return m_cache; }

IgModuleCapEntry IgModule::capabilityEntryPoint ( void   )  [protected]

Definition at line 295 of file IgModule.cc.

References empty, lat::SharedLibrary::function(), LFplugin_manager, library(), libraryName(), LOG, s_capEntryPoint, and GsfMatrixTools::trace().

Referenced by query().

00296 {
00297     lat::SharedLibrary::Function entry = 0;
00298 
00299     if (! libraryName ().empty ()) 
00300     {
00301         // Swallow errors, just return null if it fails
00302         try { entry = library ()->function (s_capEntryPoint); }
00303         catch (lat::Error &) {}
00304 
00305         LOG (0, trace, LFplugin_manager, "capability entry point ("
00306              << s_capEntryPoint << ") = " << (void *) entry << '\n');
00307     }
00308 
00309     return reinterpret_cast<IgModuleCapEntry> (entry);
00310 }

bool IgModule::checkEntryPoints ( void   )  const [protected, virtual]

Definition at line 247 of file IgModule.cc.

References lat::Error::clone(), e, IgPluginManager::ErrorEntryFailure, IgPluginManager::feedback(), lat::SharedLibrary::function(), library(), m_libraryName, m_manager, s_capEntryPoint, s_modEntryPoint, and IgPluginManager::StatusEntries.

Referenced by load().

00248 {
00249     // Check for module entry points.  It's legal to have just one or both
00250     // of the normal and capability entry points, but not to have neither.
00251     // First check for the capability entry point, then for the standard one.
00252     // If either succeeds, we declare success.  If both fail, we record the
00253     // error from the standard entry point for more meaningful errors.
00254     m_manager->feedback (IgPluginManager::StatusEntries, m_libraryName);
00255 
00256     try
00257     {
00258         if (library ()->function (s_capEntryPoint))
00259             return true;
00260     }
00261     catch (lat::Error &)
00262     {
00263     }
00264 
00265     try
00266     {
00267         return library ()->function (s_modEntryPoint);
00268     }
00269     catch (lat::Error &e)
00270     {
00271         m_manager->feedback (IgPluginManager::ErrorEntryFailure, m_libraryName, &e);
00272         throw IgPluginError (e.clone ());
00273     }
00274 }

void IgModule::clearCache ( void   )  [protected]

Definition at line 186 of file IgModule.cc.

References m_cache, and makeCache().

Referenced by bad(), and query().

00187 { delete m_cache; makeCache (); }

void IgModule::detach ( void   )  [virtual]

Definition at line 340 of file IgModule.cc.

References IgModuleDef::detach(), empty, IgPluginManager::feedback(), i, lat::indent(), LFplugin_manager, libraryName(), loaded(), LOG, m_attached, m_definition, m_infos, m_libraryName, m_manager, IgModuleDef::release(), IgPluginManager::StatusDetaching, GsfMatrixTools::trace(), and lat::undent().

Referenced by unload().

00341 {
00342     if (loaded () && m_attached && ! libraryName ().empty ())
00343     {
00344         LOG (0, trace, LFplugin_manager,
00345              "detaching module " << libraryName () << '\n' << lat::indent);
00346 
00347         m_manager->feedback (IgPluginManager::StatusDetaching, m_libraryName);
00348         for (InfoIterator i = m_infos.begin (); i != m_infos.end (); ++i)
00349             (*i)->detach ();
00350 
00351         // Capability-only modules don't have a definition.
00352         if (m_definition)
00353         {
00354             m_definition->detach ();
00355             m_definition->release ();
00356             m_definition = 0;
00357         }
00358         LOG (0, trace, LFplugin_manager, lat::undent);
00359     }
00360 }

void IgModule::detachInfo ( IgPluginInfo info  ) 

Definition at line 214 of file IgModule.cc.

References ASSERT, find(), m_infos, m_manager, and IgPluginManager::removeInfo().

Referenced by IgPluginInfo::~IgPluginInfo().

00215 {
00216     // Remove from the list but keep the details in the cache.  Also
00217     // notify the plug-in database so that this gets removed from the
00218     // factories.
00219     InfoList::iterator pos = std::find (m_infos.begin (), m_infos.end (), info);
00220     ASSERT (pos != m_infos.end ());
00221     m_infos.erase (pos);
00222     m_manager->removeInfo (info);
00223 }

IgModule::InfoIterator IgModule::endInfos ( void   )  const

Definition at line 199 of file IgModule.cc.

References m_infos.

00200 { return m_infos.end (); }

lat::SharedLibrary * IgModule::library ( void   )  const [protected]

Definition at line 98 of file IgModule.cc.

References ASSERT, lat::Error::clone(), e, lat::Filename::empty(), IgPluginManager::ErrorLoadFailure, IgPluginManager::feedback(), LFplugin_manager, lat::SharedLibrary::load(), LOG, m_library, m_libraryName, m_manager, IgPluginManager::StatusLoading, and GsfMatrixTools::trace().

Referenced by capabilityEntryPoint(), checkEntryPoints(), load(), and moduleEntryPoint().

00099 {
00100     // FIXME: return SharedLibrary::self if m_libraryName is empty?
00101     if (m_libraryName.empty ())
00102         return 0;
00103 
00104     if (! m_library)
00105     {
00106         LOG (0, trace, LFplugin_manager,
00107              "loading shared library `" << m_libraryName << "'\n");
00108 
00109         try
00110         {
00111             m_manager->feedback (IgPluginManager::StatusLoading, m_libraryName);
00112             // FIXME: remove cast when filename is in the same namespace/gcc bug fixed
00113             m_library = lat::SharedLibrary::load ((const std::string &) m_libraryName);
00114         }
00115         catch (lat::Error &e)
00116         {
00117             m_manager->feedback (IgPluginManager::ErrorLoadFailure, m_libraryName, &e);
00118             throw IgPluginError (e.clone ());
00119         }
00120     }
00121 
00122     ASSERT (m_library);
00123     return m_library;
00124 }

const lat::Filename & IgModule::libraryName ( void   )  const

Definition at line 83 of file IgModule.cc.

References m_libraryName.

Referenced by attach(), capabilityEntryPoint(), detach(), moduleEntryPoint(), IgPluginInfo::noFactory(), IgModuleCache::FileByName::operator()(), and query().

00084 { return m_libraryName; }

void IgModule::load ( void   )  [virtual]

Definition at line 131 of file IgModule.cc.

References checkEntryPoints(), lat::Filename::empty(), LFplugin_manager, library(), LOG, m_libraryName, GsfMatrixTools::trace(), and VERIFY.

00132 {
00133     if (m_libraryName.empty ())
00134         return;
00135 
00136     LOG (0, trace, LFplugin_manager, "loading `" << m_libraryName << "'\n");
00137 
00138     VERIFY (library ());
00139     VERIFY (checkEntryPoints ());
00140 }

bool IgModule::loaded ( void   )  const [protected]

Definition at line 127 of file IgModule.cc.

References lat::Filename::empty(), m_library, and m_libraryName.

Referenced by detach().

00128 { return m_libraryName.empty () || m_library;}

void IgModule::makeCache ( void   )  [protected]

Definition at line 173 of file IgModule.cc.

References bad(), m_bad, m_cache, m_libraryName, m_time, lat::Filename::nondirectory(), s_tag, and time().

Referenced by clearCache(), and IgModule().

00174 {
00175     char time [40]; // 128+ bits
00176     const char *bad = m_bad ? "bad" : "good";
00177     sprintf (time, "%lu", (unsigned long) m_time);
00178 
00179     // Ask each module to dump itself under myself.
00180     m_cache = new IgModuleDescriptor (0, s_tag,
00181                                       m_libraryName.nondirectory ().name (),
00182                                       time, bad);
00183 }

IgPluginManager * IgModule::manager ( void   )  const

Definition at line 79 of file IgModule.cc.

References m_manager.

Referenced by IgPluginInfo::noFactory().

00080 { return m_manager; }

IgModuleEntry IgModule::moduleEntryPoint ( void   )  [protected]

Definition at line 277 of file IgModule.cc.

References empty, lat::SharedLibrary::function(), LFplugin_manager, library(), libraryName(), LOG, s_modEntryPoint, and GsfMatrixTools::trace().

Referenced by attach(), and query().

00278 {
00279     lat::SharedLibrary::Function entry = 0;
00280 
00281     if (! libraryName ().empty ()) 
00282     {
00283         // Swallow errors, just return null if it fails
00284         try { entry = library ()->function (s_modEntryPoint); }
00285         catch (lat::Error &) {}
00286 
00287         LOG (0, trace, LFplugin_manager, "module entry point ("
00288              << s_modEntryPoint << ") = " << (void *) entry << '\n');
00289     }
00290 
00291     return reinterpret_cast<IgModuleEntry> (entry);
00292 }

IgModule& IgModule::operator= ( const IgModule  )  [private]

void IgModule::query ( void   )  [virtual]

Definition at line 363 of file IgModule.cc.

References ASSERT, IgModuleDef::bind(), capabilityEntryPoint(), clearCache(), IgPluginFactoryImplBase< Types >::declare(), empty, IgPluginManager::feedback(), IgPluginCapabilities::get(), i, lat::indent(), LFplugin_manager, libraryName(), LOG, m_definition, m_infos, m_libraryName, m_manager, moduleEntryPoint(), n, names, IgModuleDef::query(), IgModuleDef::release(), IgPluginManager::StatusQuerying, GsfMatrixTools::trace(), and lat::undent().

00364 {
00365     if (! libraryName ().empty ()) 
00366     {
00367         ASSERT (! m_definition);
00368 
00369         LOG (0, trace, LFplugin_manager,
00370              "querying module " << libraryName () << '\n' << lat::indent);
00371 
00372         // Blast away existing infos and the cache in order to rebuild
00373         // a clean state from the newly created infos.
00374         clearCache ();
00375         while (! m_infos.empty ())
00376             delete *m_infos.begin ();
00377 
00378         // Now invoke the standard entry point.
00379         if (IgModuleEntry entry = moduleEntryPoint ())
00380         {
00381             m_definition = (*entry) ();
00382             ASSERT (m_definition);
00383 
00384             m_manager->feedback (IgPluginManager::StatusQuerying, m_libraryName);
00385             m_definition->bind (this);
00386             m_definition->query ();
00387             m_definition->release ();
00388             m_definition = 0;
00389         }
00390 
00391         // Repeat with capabilities entry, processing it manually as
00392         // if the code was in the entry point in the module library.
00393         // This allows libraries to define "caability" modules with
00394         // pure string labels without linking against us -- but not
00395         // anything that needs a factory.  These would normally be
00396         // used for side-effects or libraries that self-register to
00397         // some other factory.  NB: The code below creates a module
00398         // definition even if the module has a standard entry point
00399         // and thus an existing definition.  Since this is a query,
00400         // different defs don't matter, and attach will never use
00401         // the def anyway.
00402         if (IgModuleCapEntry capEntry = capabilityEntryPoint ())
00403         {
00404             IgModuleDef *def = new IgModuleDef;
00405             const char  **names = 0;
00406             int         n = -1;
00407 
00408             (*capEntry) (names, n);
00409 
00410             def->bind (this);
00411             for (int i = 0; names && names [i] && (n < 0 || i < n); ++i)
00412                 IgPluginCapabilities::get ()->declare (def, names [i]);
00413             def->release ();
00414             delete def;
00415         }
00416 
00417         LOG (0, trace, LFplugin_manager, lat::undent);
00418     }
00419 }

void IgModule::restore ( IgModuleDescriptor info  )  [protected, virtual]

Definition at line 227 of file IgModule.cc.

References IgModuleDescriptor::dup(), m_cache, m_manager, and IgPluginManager::restore().

Referenced by IgModuleCache::reconstruct().

00228 {
00229     // FIXME: If factory is active, this will result in creation of a new
00230     // info, which we'll want to add to our cache.  Make sure we don't
00231     // make duplicates...
00232     from->dup (m_cache);
00233     m_manager->restore (this, from);
00234 }

const char * IgModule::tag ( void   )  [inline, static, protected]

Definition at line 146 of file IgModule.h.

References s_tag.

Referenced by IgModuleCache::makeBad(), IgModuleCache::reconstruct(), and IgModuleCache::scanModules().

00147 { return s_tag; }

unsigned IgModule::time ( void   )  const [inline]

Return the registration file time stamp.

Definition at line 151 of file IgModule.h.

References m_time.

Referenced by makeCache().

00152 { return m_time; }

void IgModule::unload ( void   )  [virtual]

Definition at line 143 of file IgModule.cc.

References lat::SharedLibrary::abandon(), detach(), lat::Filename::empty(), IgPluginManager::feedback(), LFplugin_manager, LOG, m_library, m_libraryName, m_manager, lat::SharedLibrary::release(), IgPluginManager::StatusUnloading, and GsfMatrixTools::trace().

Referenced by ~IgModule().

00144 {
00145     if (m_libraryName.empty ())
00146         return;
00147 
00148     detach ();
00149 
00150     // Do not unload libraries on platforms with broken handling of
00151     // global destructors in shared libraries (e.g. KCC 4.0f on
00152     // Linux).  The problem is that global destructors are not
00153     // deregistered on library unload, causing instability with
00154     // subsequent dynamic loading operations, program exit etc.
00155     if (m_library)
00156     {
00157         LOG (0, trace, LFplugin_manager, "unloading `" << m_libraryName << "'\n");
00158 
00159         if (lat::ShellEnvironment ().has ("IGUANA_RELEASE_MODULES"))
00160         {
00161             m_manager->feedback (IgPluginManager::StatusUnloading, m_libraryName);
00162             m_library->release ();
00163         }
00164         else
00165             m_library->abandon ();
00166 
00167         m_library = 0;
00168     }
00169 }


Friends And Related Function Documentation

friend class IgModuleCache [friend]

Definition at line 107 of file IgModule.h.


Member Data Documentation

bool IgModule::m_attached [private]

Definition at line 130 of file IgModule.h.

Referenced by attach(), attached(), and detach().

bool IgModule::m_bad [private]

Definition at line 129 of file IgModule.h.

Referenced by bad(), and makeCache().

IgModuleDescriptor* IgModule::m_cache [private]

Definition at line 126 of file IgModule.h.

Referenced by cache(), cacheRoot(), clearCache(), makeCache(), restore(), and ~IgModule().

IgModuleDef* IgModule::m_definition [private]

Definition at line 131 of file IgModule.h.

Referenced by attach(), detach(), and query().

InfoList IgModule::m_infos [private]

Definition at line 132 of file IgModule.h.

Referenced by addInfo(), beginInfos(), detach(), detachInfo(), endInfos(), query(), and ~IgModule().

lat::SharedLibrary* IgModule::m_library [mutable, private]

Definition at line 125 of file IgModule.h.

Referenced by library(), loaded(), unload(), and ~IgModule().

lat::Filename IgModule::m_libraryName [private]

Definition at line 124 of file IgModule.h.

Referenced by attach(), checkEntryPoints(), detach(), IgModule(), library(), libraryName(), load(), loaded(), makeCache(), query(), unload(), and ~IgModule().

IgPluginManager* IgModule::m_manager [private]

Definition at line 123 of file IgModule.h.

Referenced by addInfo(), attach(), checkEntryPoints(), detach(), detachInfo(), library(), manager(), query(), restore(), and unload().

unsigned IgModule::m_time [private]

Definition at line 128 of file IgModule.h.

Referenced by makeCache(), and time().

const char IgModule::s_capEntryPoint = "IGUANA_CAPABILITIES" [static, private]

Definition at line 134 of file IgModule.h.

Referenced by capabilityEntryPoint(), and checkEntryPoints().

const char IgModule::s_modEntryPoint = "IGUANA_MODULE" [static, private]

Definition at line 133 of file IgModule.h.

Referenced by checkEntryPoints(), and moduleEntryPoint().

const char IgModule::s_tag = "module" [static, private]

Definition at line 135 of file IgModule.h.

Referenced by makeCache(), and tag().


The documentation for this class was generated from the following files:
Generated on Tue Jun 9 18:25:13 2009 for CMSSW by  doxygen 1.5.4