Boost logo

Boost :

From: Ion Gaztañaga (igaztanaga_at_[hidden])
Date: 2007-05-24 12:06:51


dherring_at_[hidden] wrote:
> Hi,
>
> I think there's a minor mistake in the template code for
> interprocess_condition::wait.
>
>
> ***** Begin example *****
> using namespace boost::interprocess;
>
> #ifdef USE_RECURSIVE
> typedef interprocess_recursive_mutex MutexT;
> #else
> typedef interprocess_mutex MutexT;
> #endif
>
> MutexT mutex;
> scoped_lock<MutexT> lock(mutex);
> interprocess_condition condition;
> condition.wait(lock); // compilation error when USE_RECURSIVE is defined
> ***** End example *****
>
>
> Here, wait() is templated on the lock type; but this calls do_wait(),
> which requires interprocess_mutex. Is there a reason why do_wait()
> cannot accept a recursive mutex?

interprocess_mutex is implemented as a pthread mutex with a
PTHREAD_PROCESS_SHARED attribute. If the implementation supports also
recursive mutexes it uses pthread_set_type(PTHREAD_MUTEX_RECURSIVE) to
activate a recursive mutex. POSIX (IEEE Std 1003.1, 2003 Edition)
explicitly states in the application usage of
pthread_mutexattr_gettype/pthread_mutexattr_settype:

"It is advised that an application should not use a
PTHREAD_MUTEX_RECURSIVE mutex with condition variables because the
implicit unlock performed for a pthread_cond_timedwait() or
pthread_cond_wait() may not actually release the mutex (if it had been
locked multiple times). If this happens, no other thread can satisfy the
condition of the predicate."

Which means that if a recursive mutex is used the mutex is not really
unlocked because the lock count was higher than 0, so no other thread
will change the predicate to wake up the thread. I guess this problem
would also appear with emulation code.

Regards,

Ion


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk