Hi Robert,

You do have to understand that what is currently happening is an
implicit init/destroyOsg through DllMain. The problem is that DllMain is
full of limitations. Only a handful of kernel functions can be safely
called in DllMain. Worse, Microsoft in all their wisdom does not provide
the list of safe functions.

According to DllMain documentation on MSDN, and due to the fact that
it's an implementation detail, calling any C standard functions in
DllMain is undefined behaviour. Our "particular" scenario is just one
possible way things can go wrong. MSDN documentation states that an
access violation error is also possible.


I've been thinking last night to try finding a solution to the problem
that is less intrusive on the API than an explicit init/destroyOsg. I
was thinking of using a "lazy initialisation" on any singleton that
makes a C function call. For example:

static const char * env = getenv("OSG_GL_EXTENSION_DISABLE");

could be replaced by

static Mutex s_mutex;

const char * getSingletonGlExtensionDisable()
{
    ScopedLock lock(s_mutex);

    static const char * env = getenv("OSG_GL_EXTENSION_DISABLE");

    return env;
}


Such a solution guarantees that no C functions is called in DllMain
during DLL loading (note that the Mutex construction is guaranteed to be
safe by MSDN doc). Although, destruction of the singletons still occurs
in DllMain, so it should be checked that the singleton destructors do
not call any C functions.

I'm aware that such a solution does have a performance impact because of
the mutex (the mutex is mandatory to guarantee thread safety). However,
if an object needs to often access a singleton, it can cache the
returned pointer (once an object's got the singleton, it is safe to use
the returned pointer without having to call getSingleton() again and
again, except of course when DllMain is called to unload the DLL).

It's not a perfect solution, but I think it's better than the current
undefined behaviour. What do you think?

Regards,

Tanguy


-----Original Message-----
From: osg-users-boun...@lists.openscenegraph.org
[mailto:osg-users-boun...@lists.openscenegraph.org] On Behalf Of Robert
Osfield
Sent: 05 August 2009 13:26
To: OpenSceneGraph Users
Subject: Re: [osg-users] Deadlock when loading osg.dll, singletons are
evil

Hi Tanguy,

On Wed, Aug 5, 2009 at 12:55 PM, Tanguy
Fautre<tang...@aristechnologies.com> wrote:
> To come back to the deadlock issue, I don't think there is any way to
fix it without breaking the current OSG API compatibility. While I would
favour removing the singletons (and would heavily suggest other designs
for OSG 3.0), I perfectly understand and agree with you that such an
approach is unacceptable in the short term.

Um... I have yet to see a compelling reason for not using singletons
like Registry or a decent proposal for a replacement.   For OSG-3.0 my
plan is to focus on refactoring just the core scene graph and how
rendering is implemented, for the rest of the API changes we should
keep as minimal as possible to try and reduce to headache of porting
from OSG-2.x to OSG-3.x.  We can't avoid refactoring the core scene
graph state management to be able to do shader composition, but the
rest of changes we minimize.

> The least disruptive solution I can think of (while being quite
robust) would be to introduce an initOsg() and a destroyOsg() function.
It's a fairly common approach and is in fact the one mandated by MSDN
regarding the limitations of DllMain (and the deadlocks that may follow
if violated).

My gut reaction is YUK.   Design wise, implementation wise and support
wise I know it's a hack.


> initOsg() would initialize and construct all the global variables of
Osg when called, while destroyOsg() would take care of the destruction
of such objects.

OK. So this uber initOsg() method would need to initialize all global
variables and hence know about all global variance and hence be
tightly coupled with all global variables.  Now if you have a very
simply set of libs to work with, and everything is fixed in it's
relationship this might work, but... if you have a loosely coupled
design that allows you to extend it at runtime what then??  For
instance NodeKits... who inits these?   Do we have explict init's for
each NodeKit the user might use.  What about NodeKits that are pulled
in at runtime to enable the loading of a particular databases?


> The benefits are twofold:
> - The user would have a better control on the lifetime of the OSG and
its global variables (among other things, solving the deadlock issue
exposed in this discussion).
> - The user would have the ability to reset the library in a
predictable manner, which is currently impossible.
>
> A few points should be observed:
> 1. init/destroyOsg needs to be referenced counted (allowing multiple
and re-entrant initializations)
> 2. init/destroyOsg needs to be thread-safe
> 3. init/destroyOsg needs to be aware that osg is divided into several
components (e.g. osg, osgDB, osgViewer, etc). It would probably be
needed that the user can in fact select which components of osg he wants
to init/destroy (in which case points 1 and 2 need to be done per
component).

OK state all possible benefits and ignore the monstrous downsides such
as tight coupling and blowing out of the water the extensibility that
the OSG is known for.

I sure want to see a good solution to the problems you are seeing but
I won't idly stand by while the OSG is made less easy to use and less
extensible. You go explain to all the thousands of OSG users that
having to re-factor they code for no gain, whilst compromising in
extensibility that just supporting your particular usage pattern.

What we have at hand is very specific issue that occurs when a very
specific set of things are done in a client application, it's not a
general problem that requires a major re-factor.  Careful initiation
at your end may well be the solution.

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

Reply via email to