|
Threads-Devel : |
From: Anthony Williams (anthony_at_[hidden])
Date: 2007-06-20 09:42:12
"Petru Marginean" <petru.marginean_at_[hidden]> writes:
> I would like to re-implement this (callback) function that currently uses
> pthreads:
>
> pthread_mutex_t mutex;
> int i = pthread_mutex_init(&mutex, 0);
>
> void MutexCB(int lock)
> {
> if (lock)
> pthread_mutex_lock(&mutex);
> else
> pthread_mutex_unlock(&mutex);
> }
>
> using the boost library (so the code will be portable).
>
> The function is necessary in order to use some third party API.
> It has to lock the mutex if 'lock' == true, unlock it otherwise.
> It has to be thread safe as well.
> I had difficulties since the scoped_lock is NOT thread safe, and the access
> to the mutex's do_lock()/do_unlock() methods is private.
>
> Here is a solution that uses:
> - recursive mutex,
> - a static lock that gives the access to the lock/unlock mechanism
> - another lock (on the stack) that makes the static lock thread safe
>
> boost::recursive_mutex m;
>
> void MutexCB(int lock)
> {
> boost::recursive_mutex::scoped_lock l(m); // it makes the 's'lock
> thread safe
> static boost::recursive_mutex::scoped_lock s(m, false /*lock only if
> necessary*/);
> if (lock)
> s.lock();
> if (!lock)
> s.unlock();
> }
>
> As you can see it is more complicated that the pthread solution and less
> efficient, since it does a extra lock/unlock every time.
> Is it possible to write a solution at least as simple as the original one?
The short answer is "no". You could use thread_specific_ptr to have a
scoped_lock object per thread, and then lock/unlock that as required. It's
better than using an extra lock, but still more complex.
This usage is not supported well at the moment. It should improve with the
next boost release.
Anthony
-- Anthony Williams Just Software Solutions Ltd - http://www.justsoftwaresolutions.co.uk Registered in England, Company Number 5478976. Registered Office: 15 Carrallack Mews, St Just, Cornwall, TR19 7UL