On Thu, 2006-08-03 at 13:10 -0400, Thomas Fitzsimmons wrote: > the three exit conditions are: > > * There are no displayable AWT or Swing components. > * There are no native events in the native event queue. > * There are no AWT events in java EventQueues. > > The first two conditions are satisfied by quitting the GTK main thread (no > native events) when there are no windows left (no displayable AWT or Swing > components). I'm wondering if we need a check for the third condition before > quitting the GTK main loop.
Right, 1) is what I just implemented. As for 2), calling gtk_main_quit() doesn't quit immediately but rather "Makes the innermost invocation of the main loop return when it regains control." as the GTK docs say. So I'm 95% sure that's to be interpreted as the native queue being empty at that point. Condition 3) Is also fulfilled. The EventDispatchThread shuts itself down as it should, and I'm certain we don't need to check with the GTK thread. The way I read it, the first two points relate only to the main GTK thread, and the third point only to the EventDispatchThread. So basically when 1) and 2) are satisfied we can shut down the GTK thread (since the peers are disposed of at that point, the EventQueue can't call into them and cause new native events). There's no apparent reason why we'd need or want to shut them all down at the same time. Once the GTK thread is shut down the EventQueue empties itself and then shuts down. It seems to work just fine. I'm attaching a little testcase that creates and destroys some windows and prints the number of active threads. As expected we have two; the main GTK thread and the EventDispatchThread. Interestingly, the testcase shows that the 1.4 JDK revs up 6 (!) threads by then. (But 'only' 4 on the 1.5 JDK). I dunno what it's doing with all those extra threads. Running a botnet? :) /Sven
import java.awt.*; public class ThreadTest { public static void main(String[] args) { System.out.println("Thread initially active:"+Thread.activeCount()); Frame f = new Frame(); f.setSize(100,100); f.setVisible(true); System.out.println("Active after opening window:"+Thread.activeCount()); long t = System.currentTimeMillis(); System.out.println("Delaying 5s"); while( (System.currentTimeMillis() - t) < 5000 ) Thread.yield(); System.out.println("Active now:"+Thread.activeCount()); System.out.println("Disposing peers."); f.dispose(); f = null; t = System.currentTimeMillis(); System.out.println("Active now::"+Thread.activeCount()); System.out.println("Waiting 5 s"); while( (System.currentTimeMillis() - t) < 5000 ) Thread.yield(); f = new Frame(); f.setSize(100,100); System.out.println("Recreating peers."); f.setVisible(true); System.out.println("# of active threads now:"+Thread.activeCount()); System.out.println("End."); } }