From: Matt Hurd (matt.hurd_at_[hidden])
Date: 2005-04-28 19:38:55


>Michael Glassford <glassfordm_at_[hidden]> wrote:
> 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.

What is happenning on concurrent m.lock() invocations with the lock
transfer object and their subsequent simultaneous use?

Matt.