Skip to content

Commit fb0d286

Browse files
hansonrhansonr
authored andcommitted
j2sheadless should fire System.exit(0) after running main.
moving TimerQueue to ThreadGroup
1 parent a3a3866 commit fb0d286

File tree

13 files changed

+127
-44
lines changed

13 files changed

+127
-44
lines changed

sources/net.sf.j2s.java.core/src/java/awt/JSComponent.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
import javax.swing.plaf.FontUIResource;
4747
import javax.swing.plaf.UIResource;
4848

49-
import swingjs.JSAppletThread;
5049
import swingjs.JSAppletViewer;
5150
import swingjs.JSFrameViewer;
5251
import swingjs.JSGraphics2D;
@@ -115,7 +114,7 @@ public interface A2SWrappedComponent {
115114
public JSGraphics2D 秘gtemp; // indicates that we are painting, so that g.setBackground() should also be set
116115

117116
public boolean 秘isRootPane, 秘isContentPane;
118-
public JSAppletViewer 秘appletViewer = ((JSAppletThread) Thread.currentThread()).秘appletViewer;
117+
public JSAppletViewer 秘appletViewer = Thread.currentThread().getThreadGroup().秘appletViewer;
119118
private JSFrameViewer 秘frameViewer, 秘topFrameViewer;
120119
public HTML5Canvas 秘canvas;
121120
public ComponentUI ui; // from JComponent

sources/net.sf.j2s.java.core/src/java/lang/ApplicationShutdownHooks.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ static void runHooks() {
101101

102102
for (Thread hook : threads) {
103103
try {
104-
hook.start();
104+
hook.run(); // SwingJS was start(), but then this comes too late
105105
} catch (Throwable t) {
106106
// SwingJS
107107
System.err.println("ApplicationShutdownHooks exception:\n" + t);

sources/net.sf.j2s.java.core/src/java/lang/Shutdown.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,15 @@ private static void runHooks() {
164164
*/
165165
static void halt(int status) {
166166
synchronized (haltLock) {
167-
halt0(status);
167+
System.out.println("Shutdown(" + status + ") on " + Thread.currentThread().getThreadGroup().getName());
168+
// halt0(status);
168169
}
169170
}
170171

171-
static native void halt0(int status);
172+
// static native void halt0(int status);
172173

173174
/* Wormhole for invoking java.lang.ref.Finalizer.runAllFinalizers */
174-
private static native void runAllFinalizers();
175+
// private static native void runAllFinalizers();
175176

176177

177178
/* The actual shutdown sequence is defined here.
@@ -193,12 +194,12 @@ private static void sequence() {
193194
if (state != HOOKS) return;
194195
}
195196
runHooks();
196-
boolean rfoe;
197+
// boolean rfoe;
197198
synchronized (lock) {
198199
state = FINALIZERS;
199-
rfoe = runFinalizersOnExit;
200+
// rfoe = runFinalizersOnExit;
200201
}
201-
if (rfoe) runAllFinalizers();
202+
// if (rfoe) runAllFinalizers();
202203
}
203204

204205

@@ -230,7 +231,7 @@ static void exit(int status) {
230231
}
231232
}
232233
if (runMoreFinalizers) {
233-
runAllFinalizers();
234+
//runAllFinalizers();
234235
halt(status);
235236
}
236237
synchronized (Shutdown.class) {

sources/net.sf.j2s.java.core/src/java/lang/ThreadGroup.java

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@
2828

2929
package java.lang;
3030

31+
import java.util.ArrayList;
3132
//import java.io.PrintStream;
3233
import java.util.Arrays;
3334
//import sun.misc.VM;
3435

36+
import javax.swing.Timer;
37+
38+
import swingjs.JSAppletViewer;
3539
import swingjs.api.js.HTML5Applet;
3640

3741
/**
@@ -61,20 +65,23 @@
6165
public
6266
class ThreadGroup implements Thread.UncaughtExceptionHandler {
6367
private final ThreadGroup parent;
64-
String name;
65-
int maxPriority = Thread.MAX_PRIORITY; // BH
66-
boolean destroyed;
67-
boolean daemon;
68-
boolean vmAllowSuspension;
68+
private String name;
69+
private int maxPriority = Thread.MAX_PRIORITY; // BH
70+
private boolean destroyed;
71+
private boolean daemon;
72+
private boolean vmAllowSuspension;
6973

70-
int nUnstartedThreads = 0;
71-
int nthreads;
72-
Thread threads[];
74+
private int nUnstartedThreads = 0;
75+
private int nthreads;
76+
private Thread threads[];
7377

74-
int ngroups;
75-
ThreadGroup groups[];
78+
private int ngroups;
79+
private ThreadGroup groups[];
7680
protected HTML5Applet 秘html5Applet;
7781
public boolean 秘systemExited;
82+
public JSAppletViewer 秘appletViewer;
83+
84+
private ArrayList<Object> 秘timerQueue;
7885

7986
// /**
8087
// * Creates an empty Thread group that is not in any Thread group.
@@ -1043,5 +1050,20 @@ public String toString() {
10431050
return getClass().getName() + "[name=" + getName() + ",maxpri=" + maxPriority + ",html5Applet=" + 秘html5Applet + "]";
10441051
}
10451052

1053+
public ArrayList<Object> 秘getTimerQueue() {
1054+
return (秘systemExited ? null : 秘timerQueue == null ? (秘timerQueue = new ArrayList<Object>()) : 秘timerQueue);
1055+
}
10461056

1057+
public void 秘exit() {
1058+
ArrayList<Object> q = 秘getTimerQueue();
1059+
for (int i = q.size(); --i >= 0;) {
1060+
Timer t = (Timer) q.get(i);
1061+
try {
1062+
t.stop();
1063+
} catch (Throwable e) {
1064+
// ignore
1065+
}
1066+
}
1067+
秘systemExited = true;
1068+
}
10471069
}

sources/net.sf.j2s.java.core/src/javajs/util/JSThread.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
import java.awt.Toolkit;
44
import java.awt.event.InvocationEvent;
55

6-
//import javajs.J2SRequireImport;
7-
import javajs.api.JSFunction;
8-
96

107
/**
118
* An abstract class that takes care of simple threading in Java or JavaScript.

sources/net.sf.j2s.java.core/src/swingjs/JSAppletThread.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,14 @@
1717
*/
1818
public class JSAppletThread extends JSThread {
1919

20-
public JSAppletViewer 秘appletViewer;
21-
2220
public JSAppletThread(JSAppletViewer ap, ThreadGroup group, String name) {
2321
super(group, name);
24-
秘appletViewer = ap;
22+
getThreadGroup().秘appletViewer = ap;
2523
}
2624

2725
@Override
2826
public void run1(int mode) {
29-
mode = 秘appletViewer.run1(mode);
27+
mode = getThreadGroup().秘appletViewer.run1(mode);
3028
if (mode != DONE)
3129
dispatchAndReturn(null, mode);
3230
}

sources/net.sf.j2s.java.core/src/swingjs/JSAppletViewer.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -619,10 +619,6 @@ public JSFrameViewer newFrameViewer(boolean forceNew) {
619619
return (haveFrames || forceNew ? new JSFrameViewer() : null);
620620
}
621621

622-
public ArrayList<Object> getTimerQueue() {
623-
return (timerQueue == null ? (timerQueue = new ArrayList<Object>()) : timerQueue);
624-
}
625-
626622
public void exit() {
627623
for (int i = allWindows.size(); --i >= 0;)
628624
try {

sources/net.sf.j2s.java.core/src/swingjs/JSToolkit.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,11 @@ public static Object getPostEventQueue(boolean isPost) {
118118
* From System.exit()
119119
*/
120120
public static void exit(int status) {
121-
Thread.currentThread().getThreadGroup().秘systemExited = true;
122-
JSUtil.getAppletViewer().exit();
121+
122+
Thread.currentThread().getThreadGroup().秘exit();
123+
JSAppletViewer v = JSUtil.getAppletViewer();
124+
if (v != null)
125+
v.exit();
123126
Runtime.getRuntime().exit(status);
124127
}
125128

@@ -222,7 +225,7 @@ public static Object getPropertyObject(Object t, String key, Object def) {
222225
*/
223226
public static GraphicsConfiguration getGraphicsConfiguration() {
224227
JSAppletViewer ap = JSUtil.getAppletViewer();
225-
GraphicsConfiguration gc = ap.graphicsConfig;
228+
GraphicsConfiguration gc = (ap == null ? null : ap.graphicsConfig);
226229
return (gc == null ? (gc = ap.graphicsConfig = (GraphicsConfiguration) JSUtil.getInstance("swingjs.JSGraphicsConfiguration")) : gc);
227230
}
228231

@@ -688,7 +691,7 @@ public static Line getAudioLine(Line.Info info) {
688691
}
689692

690693
public static ArrayList<Object> getTimerQueue() {
691-
return JSUtil.getAppletViewer().getTimerQueue();
694+
return Thread.currentThread().getThreadGroup().秘getTimerQueue();
692695
}
693696

694697
/**

sources/net.sf.j2s.java.core/src/swingjs/JSUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ public static Object getInstance(String className) {
424424
}
425425

426426
public static JSAppletViewer getAppletViewer() {
427-
return ((JSAppletThread) Thread.currentThread()).秘appletViewer;
427+
return Thread.currentThread().getThreadGroup().秘appletViewer;
428428
}
429429

430430
public static void readyCallback(String aname, String fname, JSComponent applet,
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package test;
2+
3+
import java.awt.event.ActionEvent;
4+
import java.awt.event.ActionListener;
5+
import java.util.logging.ConsoleHandler;
6+
import java.util.logging.Handler;
7+
import java.util.logging.Level;
8+
import java.util.logging.LogRecord;
9+
import java.util.logging.Logger;
10+
11+
import javax.swing.JFrame;
12+
import javax.swing.Timer;
13+
14+
public class Test_Exit extends Test_ {
15+
16+
public static void main(String[] args) {
17+
new Test_Exit();
18+
}
19+
20+
public Test_Exit() {
21+
22+
// oddly enough, Java runs these hooks in unpredictable order,
23+
// but SwingJS will run them sequentially
24+
25+
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
26+
27+
@Override
28+
public void run() {
29+
System.out.println("OK Test_Exit 1");
30+
}
31+
32+
}));
33+
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
34+
35+
@Override
36+
public void run() {
37+
System.out.println("OK Test_Exit 2");
38+
}
39+
40+
}));
41+
42+
Timer t = new Timer(200, new ActionListener() {
43+
44+
@Override
45+
public void actionPerformed(ActionEvent e) {
46+
// System.exit(0) should prevent this from firing
47+
// but in Java, it depends upon the delay, with about 200 ms required to stop it
48+
System.out.println("NO! Test_Exit");
49+
assert(false);
50+
}
51+
52+
});
53+
t.setRepeats(false);
54+
t.start();
55+
JFrame j = new JFrame("test");
56+
j.setSize(300,300);
57+
j.setVisible(true);
58+
System.exit(0);
59+
}
60+
61+
static {
62+
// to allow the frame to pop up briefly
63+
j2sHeadless = false;
64+
}
65+
}

0 commit comments

Comments
 (0)