Finalizer deadlock
Bryce McKinlay
mckinlay@redhat.com
Wed Sep 8 20:58:00 GMT 2004
Gladish, Jacob wrote:
>This was proposed about two months ago:
>>>>>Yes, we could rewrite it using _Jv_CondWait/_Jv_CondNotify and other
>>thread primitives defined in the thread headers.
>>>>I'm also not sure this peice of code in FinalizerThread is safe:
>>public static void finalizerReady ()
>>{
>> synchronized (lock)
>> {
>> if (! thread_started)
>> runFinalizers ();
>>>>Isn't there a race here? Unlikely to happen, perhaps, but it seems like
>>>>>if >a finalizer needs to be run before the finalizer thread has finished
>>>>starting, we'll try to run finalizers from the inside the GC's thread.
>>>>Regards
>>>>Bryce
>>>>>>>>>Is this that case? The two threads are deadlocked. The finalizer is
>waiting for a monitor on the PlainSocketImpl.
>
Hmm, looking at this more, I think a race condition is still possible -
although very unlikely ...
// Main loop for the finalizer thread.
void
gnu::gcj::runtime::FinalizerThread::run ()
{
while (true)
{
_Jv_MutexLock (&mutex);
if (! finalizer_ready)
_Jv_CondWait (&condition, &mutex, 0, 0);
finalizer_ready = false;
_Jv_MutexUnlock (&mutex);
_Jv_RunFinalizers ();
}
}
If the finalizer thread were suspended by a GC cycle being invoked from
another thread, while it holds the mutex, then a deadlock could occur if
that GC then invokes finalizerReady().
Perhaps we need some kind of "GC critical section" call to ensure that
the GC does not attempt to suspend the finalizer thread while the lock
is held. Or, perhaps there is an easier solution - could this be
implemented purely with atomic operations? Java finalization sure is
tricky to implement (reliably)...
Still, I think this is very unlikely to actually happen (note that the
mutex is released by _Jv_CondWait), and is unlikely to be the cause of
the bug you saw.
Regards
Bryce
More information about the Java
mailing list