re PR awt/16748 (IAA.ImageComponentsTest: Freezes When Window Is Resized)
authorBryce McKinlay <mckinlay@redhat.com>
Sun, 11 Jul 2004 21:19:47 +0000 (21:19 +0000)
committerBryce McKinlay <bryce@gcc.gnu.org>
Sun, 11 Jul 2004 21:19:47 +0000 (22:19 +0100)
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

libjava/ChangeLog
libjava/gnu/gcj/runtime/FinalizerThread.java
libjava/gnu/gcj/runtime/natFinalizerThread.cc
libjava/prims.cc

index c7f5dec47053e491ece2917a55ec822f762a8175..49773da0b584ea360a1e02424eeac5ddf99b2955 100644 (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)
index e333d7a41c7d66140a743ea5d6c71e8758607c1a..c9a917cd264b498e54cfe2bbf284906d096c225f 100644 (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();
 }
index d296bc40551b31539aad1a5653cf2393962172ef..ec1846baf6acd2c377dad2e0a3867b24fa93d776 100644 (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::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 ();
+    }
 }
index 93db746fc1eefaa450407e4bfdeb4406400fd119..7aac58497aaa4f00e616e1bac5622917eec6d094 100644 (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;