]> git.lizzy.rs Git - rust.git/commitdiff
std: Fail more gracefully on thread spawn errors
authorAlex Crichton <alex@alexcrichton.com>
Fri, 18 Apr 2014 17:36:16 +0000 (10:36 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 18 Apr 2014 17:36:16 +0000 (10:36 -0700)
On windows, correctly check for errors when spawning threads, and on both
windows and unix handle the error more gracefully rather than printing an opaque
assertion failure.

Closes #13589

src/libstd/rt/thread.rs

index 4aa85bc4c72a624431ee6ce97217592ae4762c4c..2d952b2a9db17d462a8ff9c1eee58d6fc5a70ed5 100644 (file)
@@ -150,6 +150,7 @@ mod imp {
     use libc;
     use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES, SIZE_T, BOOL,
                                        LPVOID, DWORD, LPDWORD, HANDLE};
+    use os;
     use ptr;
     use rt::stack::RED_ZONE;
 
@@ -168,8 +169,15 @@ pub unsafe fn create(stack: uint, p: ~proc():Send) -> rust_thread {
         // kernel does, might as well make it explicit.  With the current
         // 20 kB red zone, that makes for a 64 kB minimum stack.
         let stack_size = (cmp::max(stack, RED_ZONE) + 0xfffe) & (-0xfffe - 1);
-        CreateThread(ptr::mut_null(), stack_size as libc::size_t,
-                     super::thread_start, arg, 0, ptr::mut_null())
+        let ret = CreateThread(ptr::mut_null(), stack_size as libc::size_t,
+                               super::thread_start, arg, 0, ptr::mut_null());
+
+        if ret as uint == 0 {
+            // be sure to not leak the closure
+            let _p: ~proc():Send = cast::transmute(arg);
+            fail!("failed to spawn native thread: {}", os::last_os_error());
+        }
+        return ret;
     }
 
     pub unsafe fn join(native: rust_thread) {
@@ -243,9 +251,14 @@ pub unsafe fn create(stack: uint, p: ~proc():Send) -> rust_thread {
         };
 
         let arg: *libc::c_void = cast::transmute(p);
-        assert_eq!(pthread_create(&mut native, &attr,
-                                  super::thread_start, arg), 0);
+        let ret = pthread_create(&mut native, &attr, super::thread_start, arg);
         assert_eq!(pthread_attr_destroy(&mut attr), 0);
+
+        if ret != 0 {
+            // be sure to not leak the closure
+            let _p: ~proc():Send = cast::transmute(arg);
+            fail!("failed to spawn native thread: {}", os::last_os_error());
+        }
         native
     }