Why do nested locks not cause a deadlock?

If a thread already holds a lock, then it can “take that lock” again without issue.


As to why that is, (and why it’s a good idea), consider the following situation, where we have a defined lock ordering elsewhere in the program of a -> b:

void f()
{
    lock(a)
    { /* do stuff inside a */ }
}

void doStuff()
{
    lock(b)
    {
        //do stuff inside b, that involves leaving b in an inconsistent state
        f();
        //do more stuff inside b so that its consistent again
    }
}

Whoops, we just violated our lock ordering and have a potential deadlock on our hands.

We really need to be able to do the following:

function doStuff()
{
    lock(a)
    lock(b)
    {
        //do stuff inside b, that involves leaving b in an inconsistent state
        f();
        //do more stuff inside b so that its consistent again
    }
}

So that our lock ordering is maintained, without self-deadlocking when we call f().

Leave a Comment