Raymond Chen's psychic debugging of a deadlock is everything you need to know about why the mainstream model of concurrency (in which programmer's manually manage locks and can start their own threads) is fundamentally broken.
If you're a C# or Java programmer looking at this code, you might be tempted to throw the bozo bit and say "Yech! C!" but this is precisely the same situation that one ~~can~~ will see in any kind of complex, multithreaded application.
Sure, Raymond Freakin' Chen can quickly debug such situations, but most of us don't have Raymond Freakin' Chen on staff. And no matter how gently Chen tries to show us how easy it is, most of us simply don't have the capacity to develop rapid, accurate intuitions into the cause of problematic thread behavior in this model.
And even if such capacity were widespread, the discipline of never doing any form of external calling (message sending, virtual function calls, invoking callbacks, etc.) while holding a lock is never going to be universal and, so long as it's not universal, this type of problem is inevitable.