Boost logo

Boost :

From: Michael Glassford (glassfordm_at_[hidden])
Date: 2005-04-28 19:36:38


Peter Dimov wrote:
> Michael Glassford wrote:
>
> [...]
>
> I'll think about your suggestion a bit more before I'll be able to
> comment, but just a quick note:
>
>> l = m.lock();
>> //Lock mutex m (first unlocking whatever mutex l was previously
>> locking, if any)
>
>
> This is not what will happen. m.lock() is executed first, then operator=
> is called and l is given the opportunity to release its lock. So if l
> happens to already hold m.lock(), the thread will deadlock. (And a
> deadlock can also occur if another thread holds a lock on m and is
> blocked on the mutex currently locked by l.)

Actually, the comment in my pseudo-code above is an oversimplification
of what I was actually thinking would happen. The actual transfer
mechanism (when transfering from a mutex, at least) would be that the
mutex would not actually be locked until the information was extracted
from the lock_transfer object; the steps would be:

1) The mutex would build a lock_transfer object containing enough
information to lock the mutex (this could be as simple as a this pointer
and a member function pointer, either "raw" or using boost::bind or
boost::function).
2) The lock_transfer object would be passed to the lock object's
construtor or operator=.
3) The lock object would unlock itself if it's locked.
4) The lock object would extract the information from the lock_transfer
object, which would lock the mutex in the process.

This would also have the advantage that, if the information is never
extracted from the lock_transfer object (for example, if mutex.lock()
were called but the result were not assigned to a lock object), the
mutex would never be locked.

Mike


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