re PR awt/16748 (IAA.ImageComponentsTest: Freezes When Window Is Resized)

2004-07-11  Bryce McKinlay  <mckinlay@redhat.com>

	PR libgcj/16748
	* prims.cc (_Jv_CreateJavaVM): Fix comment.
	* gnu/gcj/runtime/FinalizerThread.java (init): New. Native.
	(finalizerReady): Now native.
	(run): Likewise.
	(runFinalizers): Removed.
	* gnu/gcj/runtime/natFinalizerThread.cc (run): Implement here. Use
	a primitive lock, and don't hold it while running the finalizers.
	(runFinalizers): Implement. Don't aquire any Java lock.
	(finalizerReady): Use lock primitives to signal finalizer thread.

From-SVN: r84531
This commit is contained in:
Bryce McKinlay 2004-07-11 21:19:47 +00:00 committed by Bryce McKinlay
parent f44b0c8ec5
commit 31a7b75558
4 changed files with 64 additions and 53 deletions

View File

@ -1,3 +1,16 @@
2004-07-11 Bryce McKinlay <mckinlay@redhat.com>
PR libgcj/16748
* prims.cc (_Jv_CreateJavaVM): Fix comment.
* gnu/gcj/runtime/FinalizerThread.java (init): New. Native.
(finalizerReady): Now native.
(run): Likewise.
(runFinalizers): Removed.
* gnu/gcj/runtime/natFinalizerThread.cc (run): Implement here. Use
a primitive lock, and don't hold it while running the finalizers.
(runFinalizers): Implement. Don't aquire any Java lock.
(finalizerReady): Use lock primitives to signal finalizer thread.
2004-07-11 Mark Wielaard <mark@klomp.org>
Reported by Roman Kennke <roman@ontographics.com> (bug #9331)

View File

@ -1,6 +1,6 @@
// FinalizerThread.java -- Thread in which finalizers are run.
/* Copyright (C) 2001 Free Software Foundation
/* Copyright (C) 2001, 2004 Free Software Foundation
This file is part of libgcj.
@ -16,58 +16,17 @@ package gnu.gcj.runtime;
*/
public final class FinalizerThread extends Thread
{
// Finalizers must be run in a thread with no Java-visible locks
// held. This qualifies because we don't make the lock visible.
private static final Object lock = new Object ();
// This is true if the finalizer thread started successfully. It
// might be false if, for instance, there are no threads on the
// current platform. In this situation we run finalizers in the
// caller's thread.
private static boolean thread_started = false;
private static boolean finalizer_ready;
public FinalizerThread ()
{
super ("LibgcjInternalFinalizerThread");
setDaemon (true);
finalizer_ready = false;
init();
}
// This is called by the runtime when a finalizer is ready to be
// run. It simply wakes up the finalizer thread.
public static void finalizerReady ()
{
synchronized (lock)
{
if (! thread_started)
runFinalizers ();
else
lock.notify ();
}
}
// Actually run the finalizers.
private static native void runFinalizers ();
public void run ()
{
// Wait on a lock. Whenever we wake up, try to invoke the
// finalizers.
synchronized (lock)
{
thread_started = true;
while (true)
{
try
{
lock.wait ();
}
catch (InterruptedException _)
{
// Just ignore it. It doesn't hurt to run finalizers
// when none are pending.
}
runFinalizers ();
}
}
}
private native void init();
static native void finalizerReady();
public native void run();
}

View File

@ -1,6 +1,6 @@
// natFinalizerThread.cc - Implementation of FinalizerThread native methods.
/* Copyright (C) 2001 Free Software Foundation
/* Copyright (C) 2001, 2004 Free Software Foundation
This file is part of libgcj.
@ -15,8 +15,48 @@ details. */
#include <gnu/gcj/runtime/FinalizerThread.h>
#include <java-threads.h>
static _Jv_Mutex_t mutex;
static _Jv_ConditionVariable_t condition;
// Initialize lock & condition variable.
void
gnu::gcj::runtime::FinalizerThread::runFinalizers ()
gnu::gcj::runtime::FinalizerThread::init ()
{
_Jv_RunFinalizers ();
_Jv_MutexInit (&mutex);
_Jv_CondInit (&condition);
}
// This is called by the GC when a finalizer is ready to be
// run. It sets a flag and wakes up the finalizer thread. Note
// that this MUST NOT aquire any Java lock, as this could result in
// the hash synchronization code being re-entered: the synchronization
// code itself might need to allocate. See PR 16478.
void
gnu::gcj::runtime::FinalizerThread::finalizerReady ()
{
#ifdef __JV_NO_THREADS__
_Jv_RunFinalizers ();
#else
_Jv_MutexLock (&mutex);
finalizer_ready = true;
_Jv_CondNotify (&condition, &mutex);
_Jv_MutexUnlock (&mutex);
#endif
}
// 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 ();
}
}

View File

@ -1008,8 +1008,7 @@ _Jv_CreateJavaVM (void* /*vm_args*/)
_Jv_GCInitializeFinalizers (&::gnu::gcj::runtime::FinalizerThread::finalizerReady);
// Start the GC finalizer thread. A VirtualMachineError can be
// thrown by the runtime if, say, threads aren't available. In this
// case finalizers simply won't run.
// thrown by the runtime if, say, threads aren't available.
try
{
using namespace gnu::gcj::runtime;