Hi,

We've encountered several times a random deadlock that would happen when
starting our application. After some playing around, we've identified
the problem to be quite a subtle one.

Here is what's happening. When osg.dll (in our case the full name is
osg59-osgd.dll) gets loaded, it initializes several singletons directly
and indirectly. These initializations lead to a call to
DisplaySettings::readEnvironmentalVariables(), which in turn calls
getenv().

All would be fine if it weren't for two subtle details:

1. The singleton initializations are indirectly called from DllMain().
Unfortunately, DllMain() is fairly limited in what you can do in it. For
example, calling synchronization primitives is usually a very bad idea.

2. getenv() calls a lock (a synchronization primitive) on the
environment.

The result of combining these two points is as given in the title of
this post: a nice random deadlock.

More about DllMain:
http://msdn.microsoft.com/en-us/library/ms682583%28VS.85%29.aspx
http://msdn.microsoft.com/en-us/library/aa290048%28VS.71%29.aspx#vcconmi
xeddllloadingproblemanchor3



A few months ago, there was a heated discussion about singletons in
OpenSceneGraph. Since then, this issue as well as others have now
convinced me that singletons are not simply a bad practice, but are
actually completely broken (i.e. they do not work).

Singletons are generally considered to be an anti-pattern due to the
hidden dependencies they introduce. Google is full of papers on this,
and I can attest from our personal experience with OSG that this has
been a problem on numerous occasions. For example, to improved resource
usage, we have to keep the screengraph alive but destroy the OpenGL
context when it's not being rendered. This proved to be an extremely
difficult endeavour as we had to track all these hidden dependencies by
trial and error, and manually reset them one by one.

The aforementioned deadlock however leads me to the conclusion that
singletons are not just an anti-pattern but are completely broken.
Because of the DllMain() limitations, any C/C++ standard function is
potentially unsafe. Therefore, any singleton using a C/C++ standard
function is itself potentially unsafe if used in a DLL. All it takes is
for one of these standard functions implementation to call a
synchronization primitive that is illegal in DllMain().



Regards,

Tanguy


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

Reply via email to