|
Threads-Devel : |
Subject: [Threads-devel] Verifying boost::condition_variable_any plays nicely with boost::recursive_mutex
From: Gregory Peele ARA/CFD (gpeele_at_[hidden])
Date: 2009-01-12 16:01:16
Hello,
I've recently been tasked with writing a Java-style cross-platform
asynchronous task execution service in C++ on top of Boost Threads 1.37.
After implementing this service, my unit tests discovered some
unexpected behavior (well, unexpected to me anyways) with the way that
boost::condition_variable_any, boost::recursive_mutex, and
boost::unique_lock interact. I wanted to find out if this behavior is
intentional or if it should be considered a bug.
Basically, the problem occurs when the same thread has multiple
unique_lock objects associated with the same recursive_mutex, and then
calls condition_variable_any::wait. It appears that the condition
variable only releases one of the recursive locks, and the mutex is
still considered locked by the calling thread. All of my other methods
in the unit test that call notify_one or notify_all require acquiring a
lock on the recursive_mutex to modify non-trivial shared state checked
by the condition, so they deadlock. Refactoring the code so that the
thread never acquires more than one lock on the mutex in any call
sequence fixes the deadlock, but I feel that requiring my code
maintainers and API users to honor this restriction is excessively
unfriendly.
This behavior is unexpected to me because the Java and C#
implementations of conditions and recursive mutexes (including the
implicit ones in Object synchronization) do not have this deadlock - the
condition variable wait properly releases all locks that the thread
holds rather than just one, and when the thread waits up and reacquires
the lock, the recursive count is properly restored. Is this a bug or is
this intentional? If it is intentional, then I most likely have
misunderstood the appropriate use case for unique_lock or how condition
variables work in Boost (the different use cases for the locks are not
especially clear in the documentation) and would like to know how to
accomplish what my code tried to do.
Greg Peele
Applied Research Associates, Inc.