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