Subj : Re: Can C++ local static objects be made thread safe? To : comp.programming.threads From : gniccolai Date : Tue Feb 15 2005 05:25 pm "David Schwartz" wrote in message news:... > "Giancarlo Niccolai" wrote in message > news:95e4efda.0502121051.28c5ec0c@posting.google.com... > > > The fact is that a COFU would work in that case. But a static > > initializer instead of a COFU would not, that was the point of "change > > it with any static initializer method". The point is that a static > > initializer would require lock while checking for the item to have > > been already created, and that's where the deadlock with the reentrant > > mutex happens. > > I cannot imagine how that could conceivably be possible. If the COFU is > already intialized, the initializer code reduces to this: > > acquire_mutex(); > release_mutex(); > Sorry, maybe part of the context was lost, and I did not made anything to have my readers to remember it. Let's resume: Someone proposed to have a mutex to lock a static initializer constructor call (not pthread_once like Marcin only lately suggested, which brings other problems that I don't want to discuss now); there are snippets of code explicitly locking a static constructor initialization with a "well known" application (in the beginning) or class wide (later on the discussion) mutexes, and posts explicitly defending this approach. I was referring exactly to THAT code and THAT posts. The COFU was just a teaser or placehodler (and there's the comment sayng CHANGE IT WITH YOUR FAVORITE STATIC CONSTRUTOR for that reason). However, I admit that following the thread from 100 msgs up and understanding that I was talking about that is not likely, so I should have made it clear in each message... just I hate to repeat stuff ;-) So, the thing here is not what happens in that COFU, but that there is someone saying (and from Mariani sayings, CURRENTLY putting in a compiler) THIS scheme: the_safe_initializer() { acquire_mutex() if (! cls.initialized) //a classwide static or something the like cls.construct() // a classwide constructor or something the like release_mutex() } Now, we all know here that THIS may deadlock, even (or especially) if applied to correct/legal MT code, as we don't know what cls.construct() is doing, and as someone may i.e. legitimaly do: acquire_recursive_mutex_used_in_cls_constructor() the_safe_initializer() cls.something = change() release_recursive_mutex_used_in_cls_constructor() and this is just one of the endless *legal* pattern that may bring the_safe_initializer() to deadlock. The problem was also if making the use of the_safe_initializer() like scheme as MANDATORY, that is, automatically created by the compiler and unavoidable by the programmer, or not. I was for having such compiler generated protection scheme at least optional, if ever provided. Also, someone sustained that a scheme like the one in the_safe_initializer() is able to secure any single thread code against improper use of concurrency; I also argued against this position, because the once single thread code usually needs much more knowledge about the agents relationship to coordinate with all the other threads. Just locking its initializer provides no real protection against races, missing synchronism and deadlocks that may arise from single threaded code being put in a MT program. These are the things that were sustained, and that was my position about them. Partial extracts from this long multi-sided and parallel conversation may misguide the reader, and the repliers of my mails often tried to leverage this fact, but it is impossible to resume everytime everything. So, I hope now to have cleared my position and not being misunderstood anymore. Bests, Gian. .