c++ - Infinite recursive loop with QPluginLoader::instance() -
i have conceptual problem discuss. first made automatic system plugin loading works this:
1) given plugin file names or path(s) look.
2) can queried interface pointer , cast in appropriate plugin when found (optionally further conditions).
the templated function finding implementation looks this:
template<tinterface> tinterface *implementation(const requirements &req = requierements()) { tinterface *interface = nullptr; for(qpluginloader *loader : loaders(req)) //returns list of plugins meet requirements in req { interface = qobject_cast<tinterface*>(loader.instance()) if(interface) break; } return interface; }
according qt documentation plugin instance()
(returning root component) should "shared" between qpluginloader objects operating on same file. found out not case. above code loop infinitely when there call within plugin constructor (or in constructor called root one). because such call instantiate same plugin (among others) test requested implementation trigger yet call , forth. works fine when called outside of plugin constructors...
i trying figure out solution allow me use in constructors of plugins. far cannot think of way or mechanism stop loop hence question here. ideas!
ok answer rather simple. qpluginloader object on called instance()
must "locked" prior call of instance()
subsequent calls of instance on prohibited until first call finished - sort of mutex behaviour. prevents described problem of calling instance()
inside call instance()
on same qpluginloader (happens because of search through plugins looking possible implementations of interface, see op function that).
i accomplished tracking qpluginloader objects "in use" releasing them after instance()
finished. allows me request plugins in constructors of other plugins restriction cannot request same plugin or "parent" plugin in loading hierarchy:
if constructor(s) of plugin x requests plugin y (in constructor(s)) requests plugin z z cannot request y nor x (and y cannot request x) in own constructor(s). such attempts fail returning nullptr interface.
for completeness sake here modified function:
template<tinterface> tinterface *implementation(const requirements &req = requierements()) { tinterface *interface = nullptr; for(qpluginloader *loader : loaders(req)) //loaders() returns list of plugins meet requirements in req //and not present in m_locked { m_locked << loader; interface = qobject_cast<tinterface*>(loader.instance()) m_locked.removeone(loader); if(interface) break; } return interface; }
Comments
Post a Comment