Actually I read all your and Tony's points and may be I was misunderstood. My first question is: If mutex does not guarantee thread safety what then? static boost:mutex s_m class Singleton { //everything as before in the class }; //creative get Singleton* Singleton::creating_singleton_getter() { boost::mutex::scoped_lock lock(s_m); //allways called when entered //all other calls to this function // are blocking, so it is not possible // to enter this function twice if lock is active if(Singleton::pInstance == NULL) Singleton::pInstance = new Singleton; //does not matter how these steps are executed // and reordered by compiler, since the function // can only be entered when s_m is unlocked Singleton::getter = &non_creating_getter; //this is still guarded by locked mutex!!! } //mutex unlock //everything else as it was before So the point is: As long as Singleton::instance is called from multiple threads and these are not created from global vars before main is called, this code should be thread safe. The scenario is like this: Threads: A B C D instance instance instance //only A, B or C will get access to instance, other will wait instance // if creating get was successful, D calls the lightweigt version // of getter Static class variables are guaranteed to be initialized before main is entered: C++ standard 9.4.2 states: ... Static data members are initialized and destroyed exactly like non-local objects (3.6.2, 3.6.3). ... 3.6.2 states: ... Objects with static storage duration (3.7.1) shall be zero-initialized (8.5) before any other initialization takes place. Zero-initialization and initialization with a constant expression are collectively called static initialization; all other initialization is dynamic initialization. ... So I assume, that initialization of getter with address of a (static) class function is a constant expression and therefore is not a dynamic initialization. (Please see 5.19 of a standard especially: ... Other expressions are considered constant-expressions only for the purpose of non-local static object initialization (3.6.2). Such constant expressions shall evaluate to one of the following: ... - an address constant expression, ... An address constant expression is a pointer to an lvalue designating an object of static storage duration, a string literal (2.13.4), or a function.) Therefore there should be a guaranty that the Singleton static members are initialized before main is entered. The locked mutex guarantees that only one thread at one processor will enter the function at the same time. Isn't it so? Thanks for your ideas and answers. Best Regards, Ovanes -----Original Message----- From: Sohail Somani [mailto:s.somani@fincad.com] Sent: Tuesday, January 23, 2007 4:33 AM To: Sohail Somani; boost-users@lists.boost.org Subject: Re: [Boost-users] [general question] on threadinganddoublecheckedlocking pattern Actually, its not so much wrong as it is "working currently but will probably break at some stage". Apparently, since Solaris always runs in "total storage ordering" mode, their implementation of pthread_once is correct for those hardware platforms. Just thought I'd clarify that.
-----Original Message----- From: Sohail Somani Sent: Monday, January 22, 2007 7:25 PM To: 'boost-users@lists.boost.org' Subject: RE: [Boost-users] [general question] on threading anddoublecheckedlocking pattern
Oopsie:
http://bugs.opensolaris.org/view_bug.do?bug_id=6513516
So even the smart guys get it wrong.
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Sohail Somani Sent: Monday, January 22, 2007 5:12 PM To: boost-users@lists.boost.org Subject: Re: [Boost-users] [general question] on threading anddoublecheckedlocking pattern
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users