The JIT compiler needs to initialize any classes it loads during method compilation. However, the class initialization code can invoke the method under compilation which can dead-lock in Jato because we're holding the same per-method mutex during initialization and compilation.
While discussing this on #jato, someone brought up PTHREAD_MUTEX_RECURSIVE as a potential solution for the problem. For those of you not familiar with pthreads, PTHREAD_MUTEX_RECURSIVE allows one thread to acquire the same mutex multiple times without dead-locking which would solve the problem at hand.
I didn't feel comfortable using recursive mutexes because we don't have them in the kernel (which is usually a big clue not to do something). But as I didn't have any specific arguments against them, I did the next best thing to critical thinking and started googling around. I was hoping to find a rant from Linus Torvalds explaining why they are "crap, crap, crap" but instead I found an interesting post on comp.programming.threads by David Butenhof.
He claims that PTHREAD_MUTEX_RECURSIVE was never meant to be used as a locking solution:
But nobody was supposed to use recursive mutexes. For the original intended purpose, only the global mutex would work anyway. And if you could analyze the code paths enough to know that a separate mutex was safe, why the heck would anyone want the overhead and complication of a recursive mutex instead of just doing it right?
Now I don't know if it's true or not but the post seems to validate my thinking that recursive mutexes are pretty damn special and thus should be avoided unless you know what you are doing. And as I sure as hell don't know what I am doing, we're sticking to plain old mutexes.