> From: Peter Dimov [mailto:pdimov@mmltd.net]
> Sent: 07 August 2002 13:56
> From: "Anthony Williams" <anthwil@nortelnetworks.com>
> > > Is this possible? Without language/memory architecture
> > > support, I mean.
> >
> > See my other post for Win32Mutex and POSIXMutex skeletons
> that just have a
> > default constructor.
> >
> > My point is that you can have thread-safe lazy dynamic
> initialization,
> which
> > works for static objects without causing init-order
> problems, if you use
> the
> > appropriate primitives for each platform. On POSIX,
> pthread_once provides
> > such a mechanism;
>
> pthread_once takes a single void (*) (), there is no way to
> pass arguments,
> like the address of the mutex being initialized.

Ouch. I had forgotten that :-(

OK, we need a one-time-only initialization mechanism, such as the following (adjusted for exception safety, and proper destruction of the std::set);

pthread_rwlock_t setRWLock;
pthread_once_t setFlag=PTHREAD_ONCE_INIT;

std::set<pthread_mutex_t*>* initSet;

extern "C"
{
        void doInitSet()
        {      
                pthread_rwlock_init(&setRWLock,NULL);
                initSet=new std::set<pthread_mutex_t*>;
        }
}
void initMutexOnce(pthread_mutex_t* theMutex)
{
        // ensure support set/rwlock initialized
        pthread_once(&setFlag,doInitSet);

        // we're reading the set
        pthread_rwlock_rdlock(&setRWLock);

        // check whether or not mutex is initialized
        if(initSet->find(theMutex)==initSet->end())
        {
                // mutex not initialized, so change from reader to writer
                pthread_rwlock_unlock(&setRWLock);
                pthread_rwlock_wrlock(&setRWLock);

                // and initialize mutex
                pthread_mutex_init(theMutex,NULL);
                initSet->insert(theMutex);
        }
       
        pthread_rwlock_unlock(&setRWLock);
}

Admittedly, you can then only initialize one mutex at a time, but it should work, and checking for already-initialized mutexes shouldn't be too slow.

Anthony