
Hello, all ... We use Boost 1.34 in our project to provide crucial code portability between Windows, Mac OSX and Linux. However, we've run into something that doesn't seem to make sense according to the Boost documentation. Consider the following very simple program: #include "stdafx.h" #include <boost/thread.hpp> #include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp> #include <iostream> boost::mutex g_Mutex; void f1() { boost::mutex::scoped_lock lock( g_Mutex ); std::cout << "1\n"; } int main(int argc, char* argv[]) { boost::mutex::scoped_lock lock( g_Mutex ); std::cout << "main\n"; f1(); return 0; } ... under Windows XP SP2 (using VC 8.0), the output is this: main 1 ... however, under Mac OSX 10.4.10 (using Apple's gcc4.0.1), the output is: main (program hangs) The code hangs on OSX when trying to grab the mutex again in the f1() function. The Boost documentation for scoped_lock seems to say that this should not be. I'm about to test the code on Linux (Gentoo x86) as well, but i'm waiting for Boost to finish building on it. Do I not understand boost::mutex::scoped_lock? Or is this a bug? Regards, John Falling You - exploring the beauty of voice and sound http://www.fallingyou.com

On 6/26/07, John Zorko <jmzorko@mac.com> wrote:
Hello, all ... [...] boost::mutex g_Mutex;
void f1() { boost::mutex::scoped_lock lock( g_Mutex );
std::cout << "1\n"; }
int main(int argc, char* argv[]) { boost::mutex::scoped_lock lock( g_Mutex );
std::cout << "main\n";
f1();
return 0; }
... under Windows XP SP2 (using VC 8.0), the output is this:
main 1
... however, under Mac OSX 10.4.10 (using Apple's gcc4.0.1), the output is:
main (program hangs)
Trying to lock a mutex from a thread that already owns it in Boost.Threads is undefined behavior. Under Windows (because of the underlying implementation) it happens to work, but it deadlocks on other platforms. If you really want a recursive mutex you should use boost.thread recursive_mutex instead of plain mutexes. Anyways, consider that recursive mutexes are generally "Considered Harmful" [1] Also, probably this question belongs to the boost.users mailing list. HTH, gpd [1]: http://zaval.org/resources/library/butenhof1.html

Giovanni, Thanks for the quick response! However, i'm still confused, since the Boost documentation seems to say that what i'm seeing will not happen. Specifically, in the Threading Concepts documentation at http://www.boost.org/doc/html/thread/concepts.html, the following statements appear: "Unchecked Locking Strategy With an unchecked locking strategy, when a thread attempts to acquire a lock on a mutex object for which the thread already owns a lock the operation will deadlock. In general this locking strategy is less safe than a checked or recursive strategy, but it's also a faster strategy and so is employed by many libraries. Boost.Thread does not currently provide any mutex objects that use this strategy." Is there something that i'm just not understanding? On Jun 26, 2007, at 1:08 PM, Giovanni Piero Deretta wrote:
On 6/26/07, John Zorko <jmzorko@mac.com> wrote:
Hello, all ... [...] boost::mutex g_Mutex;
void f1() { boost::mutex::scoped_lock lock( g_Mutex );
std::cout << "1\n"; }
int main(int argc, char* argv[]) { boost::mutex::scoped_lock lock( g_Mutex );
std::cout << "main\n";
f1();
return 0; }
... under Windows XP SP2 (using VC 8.0), the output is this:
main 1
... however, under Mac OSX 10.4.10 (using Apple's gcc4.0.1), the output is:
main (program hangs)
Trying to lock a mutex from a thread that already owns it in Boost.Threads is undefined behavior. Under Windows (because of the underlying implementation) it happens to work, but it deadlocks on other platforms.
If you really want a recursive mutex you should use boost.thread recursive_mutex instead of plain mutexes. Anyways, consider that recursive mutexes are generally "Considered Harmful" [1]
Also, probably this question belongs to the boost.users mailing list.
HTH,
gpd
[1]: http://zaval.org/resources/library/butenhof1.html _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/ listinfo.cgi/boost
Regards, John Falling You - exploring the beauty of voice and sound http://www.fallingyou.com

On Tue, 26 Jun 2007 22:23:43 +0200, John Zorko <jmzorko@mac.com> wrote:
Giovanni,
Thanks for the quick response! However, i'm still confused, since the Boost documentation seems to say that what i'm seeing will not happen. Specifically, in the Threading Concepts documentation at http://www.boost.org/doc/html/thread/concepts.html, the following statements appear:
"Unchecked Locking Strategy With an unchecked locking strategy, when a thread attempts to acquire a lock on a mutex object for which the thread already owns a lock the operation will deadlock. In general this locking strategy is less safe than a checked or recursive strategy, but it's also a faster strategy and so is employed by many libraries.
Boost.Thread does not currently provide any mutex objects that use this strategy."
Is there something that i'm just not understanding?
As pointed out by Giovanni Piero Deretta the locking strategy implemented by boost thread leads to undefined behaviour if a thread attempts to acquire a lock on a mutex object for which the thread already owns a lock (in your case the main thread). This is stated in the documentation: http://www.boost.org/doc/html/thread/concepts.html under the paragraph: Unspecified Locking Strategy "With an unspecified locking strategy, when a thread attempts to acquire a lock on a mutex object for which the thread already owns a lock the operation results in undefined behavior.In general a mutex object with an unspecified locking strategy is unsafe, and it requires programmer discipline to use the mutex object properly. However, this strategy allows an implementation to be as fast as possible with no restrictions on its implementation. This is especially true for portable implementations that wrap the native threading support of a platform.FOR THIS REASON, THE CLASSES BOOST::MUTEX, BOOST::TRY_MUTEX AND BOOST::TIMED_MUTEX USE THIS LOCKING STRATEGY DESPITE THE LACK OF SAFETY" So far, this is the only locking strategy implemented by the boost thread library. Regards, Marco -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/

Marco, Giovanni et al, I understand completely now -- boost::thread::mutex behavior with respect to this is undefined e.g. whatever the platform does, the platform does. Thank you all for clearing this up :-) Regards, John Falling You - exploring the beauty of voice and sound http://www.fallingyou.com
participants (3)
-
Giovanni Piero Deretta
-
John Zorko
-
Marco