From: Peter Dimov (pdimov_at_[hidden])
Date: 2004-07-15 08:49:30


David Abrahams wrote:
> Matt Hurd <matt.hurd_at_[hidden]> writes:
>
>> On Wed, 14 Jul 2004 15:27:08 -0400, David Abrahams
>> <dave_at_[hidden]> wrote:
>>> "Peter Dimov" <pdimov_at_[hidden]> writes:
>>>
>>>> I have a recursive_mutex use case that's not as trivial, though.
>>>> Imagine a mutex pool with a fixed size N that protects an
>>>> unbounded set of objects (hashing the object address mod N to
>>>> determine the mutex to lock). Now when you need to protect two
>>>> objects at the same time, due to the probability of a collision
>>>> the mutexes need to be recursive. It's still not watertight,
>>>> because if the two locks are removed from each other, this seems
>>>> like a deadlock invitation; and if the two locks are made at the
>>>> same time, the recursive lock can be avoided locally.
>>>
>>> Can't you just check the hashes and only lock once in that case?
>>
>> AFAICT, you'd have to record the objects to which the specific thread
>> had the lock otherwise you can't discriminate on who owns the lock.
>
> That's only true if a given thread can lock more than two objects at
> the same time. Isn't that likely to lead to deadlock, regardless?

Yep, have you read the last sentence in the block you quoted?

Anyway: consider this (oversimplified) situation:

// f.cpp

static object o;

void f()
{
    lock( &o );
    // do things
    unlock( &o );
}

// g.cpp

void f();

static object o2;

void g()
{
    lock( &o2 );
    f();
    unlock( &o2 );
}

Since the f() lock is always nested within the g() lock, there can be no
deadlock.