Skip to content
This repository
Browse code

Merge pull request #57 from jetztgradnet/clean-shutdown

Ensure clean shutdown without calling System.exit().
  • Loading branch information...
commit 2d0aec624d306456170ec63ae6e7a6e7f850e4fa 2 parents 8036428 + b5147c8
Kresten Krab Thorup authored July 22, 2011
9  src/main/java/erjang/ERT.java
@@ -1041,6 +1041,14 @@ public static void shutdown() {
1041 1041
 			init_pid.sendb(tup);
1042 1042
 		}
1043 1043
 	}
  1044
+	
  1045
+	/**
  1046
+	 * Shutdown Kilim schedulers.
  1047
+	 */
  1048
+	/*package*/ static void shutdownSchedulers() {
  1049
+		scheduler.shutdown();
  1050
+		async_scheduler.shutdown();
  1051
+	}
1044 1052
 
1045 1053
 	static public InputStream orig_in = System.in;
1046 1054
 	static public PrintStream orig_out = System.out;
@@ -1069,5 +1077,4 @@ public static void debug(boolean condition, String text) {
1069 1077
 			debug(text);
1070 1078
 		}
1071 1079
 	}
1072  
-
1073 1080
 }
5  src/main/java/erjang/ETimerTask.java
@@ -134,4 +134,9 @@ public static long read_timer(ERef ref) {
134 134
 		
135 135
 		return -1;
136 136
 	}
  137
+	
  138
+	public static void shutdown() {
  139
+		send_timer.cancel();
  140
+		send_timer.purge();
  141
+	}
137 142
 }
3  src/main/java/erjang/Main.java
@@ -84,7 +84,6 @@ private static String guess_erl_root() {
84 84
 		
85 85
 		ERT.log.severe("Cannot find OTPROOT directory\n"
86 86
 				+ "Pass -root <dir>, or set environment variable.");
87  
-		System.exit(-1);
88 87
 		
89 88
 		return null;
90 89
 	}
@@ -162,7 +161,7 @@ public static void main(String[] args) throws Exception {
162 161
 		
163 162
 		if (!(new File(erl_bootstrap_ebindir)).exists() && !erl_bootstrap_ebindir.startsWith(EFile.RESOURCE_PREFIX)) {
164 163
 			ERT.log.severe("No bootstrap classes at: "+erl_bootstrap_ebindir);
165  
-			System.exit(1);
  164
+			throw new IllegalArgumentException("No bootstrap classes at: "+erl_bootstrap_ebindir);
166 165
 		}
167 166
 		
168 167
 		OTPMain.main(ra.toArray(new String[ra.size()]));
9  src/main/java/erjang/OTPMain.java
@@ -24,7 +24,6 @@
24 24
 import java.util.List;
25 25
 import java.util.logging.FileHandler;
26 26
 import java.util.logging.Handler;
27  
-import java.util.logging.Level;
28 27
 import java.util.logging.Logger;
29 28
 
30 29
 import erjang.driver.EDriver;
@@ -83,10 +82,18 @@ public static void start_otp_ring0(ESeq argv) {
83 82
 		EAtom am_start = EAtom.intern("start");
84 83
 		ESeq env = ERT.NIL;
85 84
 
  85
+		// launch first (initial) process, which starts OTP
86 86
 		EProc proc = new EProc(null, am_otp_ring0, am_start, ERT.NIL.cons(argv).cons(env));
87 87
 
88 88
 		ERT.run(proc);
  89
+		
  90
+		// wait for this process to terminate
89 91
 		proc.joinb();
  92
+		
  93
+		// shutdown schedulers, after the first (initial) process has stopped
  94
+		ERT.shutdownSchedulers();
  95
+		// shutdown timer task
  96
+		ETimerTask.shutdown();
90 97
     }
91 98
 
92 99
     protected static ESeq process_args(String[] args) {
31  src/main/java/erjang/console/ERLConsole.java
@@ -56,7 +56,7 @@ public ERLConsole(String title) {
56 56
     static final int HINSET = 8;
57 57
 
58 58
     public static void main(final String[] args) {
59  
-        final ERLConsole console = new ERLConsole("Erjang Console");
  59
+        ERLConsole console = new ERLConsole("Erjang Console");
60 60
 
61 61
         console.getContentPane().setLayout(new BorderLayout());
62 62
         console.setSize(700, 600);
@@ -77,7 +77,7 @@ public static void main(final String[] args) {
77 77
         pane.setBorder(BorderFactory.createLineBorder(Color.darkGray));
78 78
         console.getContentPane().add(pane, BorderLayout.CENTER);
79 79
         
80  
-        StatusBar status = new StatusBar();
  80
+        final StatusBar status = new StatusBar();
81 81
         console.getContentPane().add(status, BorderLayout.SOUTH);
82 82
                 
83 83
         console.validate();
@@ -88,12 +88,20 @@ public void windowClosing(WindowEvent e) {
88 88
                 ERT.shutdown();
89 89
             }
90 90
         });
  91
+        console.setVisible(true);
  92
+        
  93
+        Timer timer = new Timer(true);
  94
+        timer.schedule(new TimerTask() {
  95
+
  96
+			@Override
  97
+			public void run() {
  98
+				status.updateMemory();
  99
+			}}, 1000, 1000);
91 100
 
92 101
         erjang.OTPMain.add_driver(tty);
93 102
 
94 103
         Thread t2 = new Thread() {
95 104
             public void run() {
96  
-                console.setVisible(true);
97 105
                 try {
98 106
 					erjang.Main.main(args);
99 107
 				} catch (Exception e) {
@@ -108,8 +116,12 @@ public void run() {
108 116
         } catch (InterruptedException ie) {
109 117
             // ignore
110 118
         }
111  
-
112  
-        System.exit(0);
  119
+        timer.cancel();
  120
+        timer.purge();
  121
+        timer = null;
  122
+        console.setVisible(false);
  123
+        console.dispose();
  124
+        console = null;
113 125
     }
114 126
 
115 127
     private Font findFont(String otherwise, int style, int size, String[] families) {
@@ -138,7 +150,7 @@ private Font findFont(String otherwise, int style, int size, String[] families)
138 150
 @SuppressWarnings("serial")
139 151
 class StatusBar extends JPanel {
140 152
 
141  
-	  private JLabel mem_label;
  153
+	private JLabel mem_label;
142 154
 	private JLabel progress;
143 155
 
144 156
 	public StatusBar() {
@@ -168,13 +180,6 @@ public void run() {
168 180
 	    
169 181
 	    mem_label = new JLabel();
170 182
 	    add(mem_label, BorderLayout.CENTER);
171  
-	    
172  
-	    new Timer(true).schedule(new TimerTask() {
173  
-
174  
-			@Override
175  
-			public void run() {
176  
-				StatusBar.this.updateMemory();
177  
-			}}, 1000, 1000);
178 183
 	  }
179 184
 
180 185
 	  void updateMemory() {
1  src/main/java/erjang/driver/EDriverTask.java
@@ -351,7 +351,6 @@ public void execute() throws Pausable {
351 351
 				
352 352
 				if (log.isLoggable(Level.FINER)) {
353 353
 					log.finer("EXITING "+result);
354  
-					System.exit(1);
355 354
 				}
356 355
 
357 356
 			} finally {
35  src/main/java/erjang/m/erlang/ErlProc.java
@@ -271,28 +271,35 @@ public static EObject spawn(EProc proc, EObject mod, EObject fun, EObject args)
271 271
 	
272 272
 	@BIF
273 273
 	public static EObject halt(EProc proc) {
274  
-		System.exit(0);
275  
-		return null;
  274
+		return halt(proc, null);
276 275
 	}
277 276
 	
278 277
 	@BIF
279 278
 	public static EObject halt(EProc proc, EObject value) {
280  
-		ESmall val = value.testSmall();
281  
-		if (val != null) {
282  
-			System.exit(val.value);
283  
-			return null;
  279
+		int exitCode = 1;
  280
+		String message = null;
  281
+		if (value != null) {
  282
+			ESmall val = value.testSmall();
  283
+			if (val != null) {
  284
+				exitCode = val.value;
  285
+			}
  286
+			
  287
+			EString str = value.testString();
  288
+			if (str != null) {
  289
+				message = str.stringValue();
  290
+			}
284 291
 		}
285 292
 		
286  
-		EString str = value.testString();
287  
-		if (str != null) {		
288  
-			// TODO: create crash file
289  
-			log.severe("halting system: " + str.stringValue());
290  
-			System.exit(1);
  293
+		// TODO: create crash file
  294
+		if (message != null) {
  295
+			log.severe("halting system: " + message);
291 296
 		}
  297
+		else {
  298
+			log.info("halting system");
  299
+		}
  300
+		ERT.shutdown();
292 301
 		
293  
-		throw ERT.badarg(value);
294  
-		
295  
-
  302
+		return null;
296 303
 	}
297 304
 	
298 305
 	@BIF

0 notes on commit 2d0aec6

Please sign in to comment.
Something went wrong with that request. Please try again.