Opened 14 years ago

Closed 14 years ago

Last modified 14 years ago

#2219 closed Bugs (wontfix)

conditional_variable_any::any fails to release recursive_mutex when mutex has been acquired by the same thread more than one time

Reported by: brad_wade@… Owned by: Anthony Williams
Milestone: Boost 1.36.0 Component: thread
Version: Boost 1.36.0 Severity: Regression
Keywords: condition_variable_any recursive_mutex Cc:

Description

I'm having a problem where the following code used to work in boost 1.33.0 to 1.34.1 (I have removed code for brevity). However, the code now deadlocks. It appears that the problem occurs because calling wait on a conditional_variable_any variable does not release a recursive_mutex that has been acquired by the same thread more than one time.

Attachments (1)

boost_bug.txt (2.1 KB ) - added by brad_wade@… 14 years ago.
Code example

Download all attachments as: .zip

Change History (5)

by brad_wade@…, 14 years ago

Attachment: boost_bug.txt added

Code example

comment:1 by brad_wade@…, 14 years ago

I should note that this error occurs in Visual Studio 2005--I haven't tested other compilers or platforms.

comment:2 by Anthony Williams, 14 years ago

Resolution: wontfix
Status: newclosed

This works as designed. condition_variably_any::wait() calls unlock on the supplied mutex. For a recursive mutex this only does one level of unlocking.

Completely unlocking a recursive mutex is not safe in the general case. I did not realise that the old boost::condition supported it. This facility has never been tested in the boost::condition tests. I will add it to the list of breaking changes.

comment:3 by brad_wade@…, 14 years ago

I was afraid of that. The old boost::condition would unlock the mutex however many times it had been acquired and then would restore the lock count appropriately when the wait() function completed. I was pleasantly surprised when I saw that it worked. Looks like I'll need to find a workaround... Thanks for your reply.

comment:4 by gpeele@…, 14 years ago

The core issue seems to be the POSIX implementation of recursive_mutex. There is not enough information provided by POSIX to reliably save and restore the lock count, and it's not clear how much performance would have to be sacrificed to manage this state in the Boost recursive_mutex implementation. Since nothing else would require this lock state information, I assume that's why this design choice was chosen.

As mentioned, calling lock() and unlock() multiple times inside condition_variable_any in would be unsafe, especially since this is very specific to recursive_mutex and may break the behavior for other mutex types.

Note: See TracTickets for help on using tickets.