@@ -74,6 +74,8 @@ use rt::task::Task;
74
74
use rt:: thread:: Thread ;
75
75
use rt:: work_queue:: WorkQueue ;
76
76
use rt:: uv:: uvio:: UvEventLoop ;
77
+ use unstable:: atomics:: { AtomicInt , SeqCst } ;
78
+ use unstable:: sync:: UnsafeAtomicRcBox ;
77
79
use vec:: { OwnedVector , MutableVector } ;
78
80
79
81
/// The global (exchange) heap.
@@ -174,10 +176,10 @@ pub mod util;
174
176
pub fn start ( _argc : int , _argv : * * u8 , crate_map : * u8 , main : ~fn ( ) ) -> int {
175
177
176
178
init ( crate_map) ;
177
- run ( main) ;
179
+ let exit_code = run ( main) ;
178
180
cleanup ( ) ;
179
181
180
- return 0 ;
182
+ return exit_code ;
181
183
}
182
184
183
185
/// One-time runtime initialization. Currently all this does is set up logging
@@ -190,7 +192,9 @@ pub fn cleanup() {
190
192
global_heap:: cleanup ( ) ;
191
193
}
192
194
193
- pub fn run( main : ~fn ( ) ) {
195
+ pub fn run ( main : ~fn ( ) ) -> int {
196
+ static DEFAULT_ERROR_CODE : int = 101 ;
197
+
194
198
let nthreads = match os:: getenv ( "RUST_THREADS" ) {
195
199
Some ( nstr) => FromStr :: from_str ( nstr) . get ( ) ,
196
200
None => unsafe {
@@ -216,18 +220,24 @@ pub fn run(main: ~fn()) {
216
220
scheds. push ( sched) ;
217
221
}
218
222
223
+ let exit_code = UnsafeAtomicRcBox :: new ( AtomicInt :: new ( 0 ) ) ;
224
+ let exit_code_clone = exit_code. clone ( ) ;
225
+
219
226
let main_cell = Cell :: new ( main) ;
220
227
let handles = Cell :: new ( handles) ;
221
228
let mut new_task = ~Task :: new_root ( ) ;
222
- let on_exit: ~fn ( bool ) = |exit_status | {
229
+ let on_exit: ~fn ( bool ) = |exit_success | {
223
230
224
231
let mut handles = handles. take ( ) ;
225
232
// Tell schedulers to exit
226
233
for handles. mut_iter( ) . advance |handle| {
227
234
handle. send( Shutdown ) ;
228
235
}
229
236
230
- rtassert ! ( exit_status) ;
237
+ unsafe {
238
+ let exit_code = if exit_success { 0 } else { DEFAULT_ERROR_CODE } ;
239
+ ( * exit_code_clone. get ( ) ) . store ( exit_code, SeqCst ) ;
240
+ }
231
241
} ;
232
242
new_task. on_exit = Some ( on_exit) ;
233
243
let main_task = ~Coroutine :: with_task ( & mut scheds[ 0 ] . stack_pool ,
@@ -249,6 +259,10 @@ pub fn run(main: ~fn()) {
249
259
250
260
// Wait for schedulers
251
261
let _threads = threads;
262
+
263
+ unsafe {
264
+ ( * exit_code. get ( ) ) . load ( SeqCst )
265
+ }
252
266
}
253
267
254
268
/// Possible contexts in which Rust code may be executing.
0 commit comments