[interprocess] Condition variables and a recursive mutex

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? The attached diff contains one possible solution: - Template do_wait() on the mutex type. - Add "friend class interprocess_condition" to the recursive mutex (as it is in the nonrecursive mutex). This seems to work on my computer (with POSIX_SHARED_MEMORY_OBJECTS); it has't been tested with the POSIX emulation. Thanks, Daniel

dherring@ll.mit.edu 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
participants (2)
-
dherring@ll.mit.edu
-
Ion Gaztañaga