From: Bryce McKinlay Date: Sun, 11 Jul 2004 21:19:47 +0000 (+0000) Subject: re PR awt/16748 (IAA.ImageComponentsTest: Freezes When Window Is Resized) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=31a7b755582a7c046b8bd548eb9e38f8a0b3cee0;p=gcc.git re PR awt/16748 (IAA.ImageComponentsTest: Freezes When Window Is Resized) 2004-07-11 Bryce McKinlay 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 --- diff --git a/libjava/ChangeLog b/libjava/ChangeLog index c7f5dec4705..49773da0b58 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,16 @@ +2004-07-11 Bryce McKinlay + + 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 Reported by Roman Kennke (bug #9331) 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 +#include + +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 93db746fc1e..7aac58497aa 100644 --- a/libjava/prims.cc +++ b/libjava/prims.cc @@ -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;