aboutsummaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authorBryce McKinlay <mckinlay@redhat.com>2004-07-11 21:25:51 +0000
committerBryce McKinlay <bryce@gcc.gnu.org>2004-07-11 22:25:51 +0100
commite92368438add9fe47ba3c748a2c31048bcfb5b52 (patch)
tree4a3b7b1de9e89a3018d81210749e40b6db989a82 /libjava
parent6b7f11ee25cba412f796673a175eab15c9f83ea8 (diff)
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: r84532
Diffstat (limited to 'libjava')
-rw-r--r--libjava/ChangeLog13
-rw-r--r--libjava/gnu/gcj/runtime/FinalizerThread.java55
-rw-r--r--libjava/gnu/gcj/runtime/natFinalizerThread.cc44
-rw-r--r--libjava/prims.cc3
4 files changed, 63 insertions, 52 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index a17de59e239..706ed33ac07 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -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 Michael Koch <konqueror@gmx.de>
PR libgcj/16473
diff --git a/libjava/gnu/gcj/runtime/FinalizerThread.java b/libjava/gnu/gcj/runtime/FinalizerThread.java
index e333d7a41c7..c9a917cd264 100644
--- a/libjava/gnu/gcj/runtime/FinalizerThread.java
+++ b/libjava/gnu/gcj/runtime/FinalizerThread.java
@@ -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();
}
diff --git a/libjava/gnu/gcj/runtime/natFinalizerThread.cc b/libjava/gnu/gcj/runtime/natFinalizerThread.cc
index d296bc40551..ec1846baf6a 100644
--- a/libjava/gnu/gcj/runtime/natFinalizerThread.cc
+++ b/libjava/gnu/gcj/runtime/natFinalizerThread.cc
@@ -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::init ()
+{
+ _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::runFinalizers ()
+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 ();
+ }
}
diff --git a/libjava/prims.cc b/libjava/prims.cc
index 06791d388f3..da8f36db01b 100644
--- a/libjava/prims.cc
+++ b/libjava/prims.cc
@@ -956,8 +956,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;