[omniORB] omniInitialRefLister

Bruce Visscher visschb@rjrt.com
Fri, 16 Jul 1999 11:24:13 -0400



"Ji-Yong D. Chung" wrote:
>     How does function scope thing work?  I have seen methods that
> basically
> use global static pointer variables as a flag.  If the pointer value
> is non-nil, one knows
> that the initialization has been done, and so one can proceed on other
> object
> creation that depends on the initialization.  If it is nil, then, one
> must invoke
> proper global method to initialize the object before trying to create
> other objects
> that depends on the initialization.

The method that I now tend to use (this has evolved over time).  In this
example, I'll use auto_ptr, but you could just as well use a reference
counted pointer such as a _var type.

#include <memory>
#include <SingletonLock.hxx>  // for template <typename Owner, typename
Resource>

class MySingleton {
public:
    static MySingleton& Instance();
private:
    MySingleton() {/*...*/}
    // not implementated:
    MySingleton(MySingleton const&);
    MySingleton& operator=(MySingleton const&);
};

MySingleton& MySingleton::Instance() {
    static auto_ptr<MySingleton>* p(0);
    if (!p) {
        SingletonLock<MySingleton, MySingleton> lock;
        if (!p) {
            static auto_ptr<MySingleton> q(new MySingleton);
            p=&q;
        }
    }
    return **p;
}

Notes:

1. I use a pointer to an auto_ptr rather than auto_ptr to take advantage
of initialization to 0 of built-in types (that occurs before all other
initiailization).

2. The SingletonLock class is used to avoid a "chicken-and-egg"
problem.  It's constructor utilizes pthread_once on a POSIX
implementation.  I don't know how to do this on NT.

3. The double check on !p is for performance to avoid the lock in most
cases.

4. This cries out to be templatized.

5. I hope this doesn't start another "C++ is too complicated" thread
:-).

Bruce