> Could you explain what you've done in more fine grained steps so that
> others will be able to understand what approach you've taken so that
> when they try the same thing they don't need to go through the same
> learning curve.
> 

Ok, I think the problem is not osg specific. I think it is related to
all designs dealing with reference pointers, singletons and plugins.
Singletons are often implemented with some kind of static variables as 
the "getInstance" methods should only create the instance at the first 
call.

The problem is, that static instances are destructed after the main
section of a c program. (In my concrete example at __cxa_finalize()).

So lets construct an example. There a singleton data manager which
holds reference pointers to external instances. The implementation of
these external instances is divided into an plugin system. The
base type of all plugins is defined and implemented in a library.
The data manager only knows the base type an holds the instances maybe
as std::vector<ref_pointer<BaseClass> >.

If you now write a plugin where the class DerivedClass:public BaseClass
is implemented your plugin loader will do the following steps.
1) Load the plugin with (dlopen, LoadLibrary, ...)
2) Find an extern "C" method which creates an instance of DerivedClass
   (dlsym, GetProcAddress, ...)
3) Call this method and register the instance of DerivedClass at the
   data manager

This works, so lets go to application shutdown (ore a reconfiguration
process). There one might want to close all loaded plugins (dlclose,
FreeLibrary). If these methods are called (often enough, depending,
how often the plugins where loaded) the plugin code is removed
from the address space. 
If the destructor of the data manager is called after removing the
plugins then it will fail. Let's assume that then reference pointers
to our instances are the last ones. So after decrementing the
reference counters the destructors of the derived classes are called
but they are no longer in the address space as we unloaded the plugins.

So one solution could be tho handle the plugin unloading procedure in
the destructor of the data manager. Then the described problem is
solved. But if there are other singletons (whose code is in a plugin)
there is now assumption in which order their static variables will
be destructed. If the data manager is destructed before some other
singleton then the issue occures when whose instance is destructed.

And the problems can be more complex. If one uses several frameworks
whith different singleton and reference pointer implementations
(as in my case) then one has to deal with more than one base class,
data manager and so on.

So my solution is to use the RTLD_NODELETE flag when loading my plugins.
So dlclose just removes some memory allocated by dlopen and does not
unload the code of my derived classes. In windows there is no 
comparabled flag, so I implemented the workaround described at the
link I gave in the email before.

I hope this was a useful explanation and one remembers If similar
issues occure. I am also interested in a more general solution.
Is it possible to put a code sequence after the destruction of
static variables?

Timo



_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to