summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-04-18 10:36:16 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-04-18 10:36:16 -0700
commitc318d72b8651e40559c40455475f730cf5f07a1f (patch)
tree2dde7c982a41872eb865ef794d60966dfb3a4590 /src/libstd
parentce2bab68d69ee04e17c0165dbdb7b583d5a7c991 (diff)
downloadrust-c318d72b8651e40559c40455475f730cf5f07a1f.tar.gz
rust-c318d72b8651e40559c40455475f730cf5f07a1f.zip
std: Fail more gracefully on thread spawn errors
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
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/rt/thread.rs21
1 files changed, 17 insertions, 4 deletions
diff --git a/src/libstd/rt/thread.rs b/src/libstd/rt/thread.rs
index 4aa85bc4c72..2d952b2a9db 100644
--- a/src/libstd/rt/thread.rs
+++ b/src/libstd/rt/thread.rs
@@ -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 @@ mod imp {
         // 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 @@ mod imp {
         };
 
         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
     }