4. Priority inversion - This is not an error per se, but an important issue that occurs Of these problems, locking twice is probably the easiest type of error to detect. Here's one example:

So-called "recursive" locks can deal with this situation correctly, though normal locks will cause this thread to wait forever when the function g(), when called fromf(), then calls lock(L) on a previously-held lock. Dealing with this can lead to a common code pattern with certain functions designed only to be called with locks held:

function f(){

function g() {

Failure to unlock is slightly more dif?cult to detect. It can occur, for example, if the programmer forgets to release the lock in one of the possible execution branches of the function:

function f() {lock();if (x==0) {// should also unlock here before returning!return;}// do somethingunlock();return;}

One way to deal with this is just to remember to unlock() at each possible return. Another is to have every return path go through the same section of code (and in C, goto is sometimes useful for this, despite its bad reputation).