Skip to content

Commit d371af9

Browse files
librustrt: Chrome's pthreads always errors (with errno == 22/bad argument) when
one tries to detach after creation. Creating a detached thread succeeds, so this switches to doing that instead of detching after creation.
1 parent 3fa6bc5 commit d371af9

File tree

1 file changed

+25
-16
lines changed

1 file changed

+25
-16
lines changed

src/librustrt/thread.rs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ impl Thread<()> {
8585
*mem::transmute::<&Box<Option<T>>, *const *mut Option<T>>(&packet)
8686
};
8787
let main = proc() unsafe { *packet2 = Some(main()); };
88-
let native = unsafe { imp::create(stack, box main) };
88+
let native = unsafe { imp::create(stack, box main, false).unwrap() };
8989

9090
Thread {
9191
native: native,
@@ -108,8 +108,7 @@ impl Thread<()> {
108108
/// stack size for the new thread.
109109
pub fn spawn_stack(stack: uint, main: proc():Send) {
110110
unsafe {
111-
let handle = imp::create(stack, box main);
112-
imp::detach(handle);
111+
imp::create(stack, box main, true);
113112
}
114113
}
115114

@@ -159,7 +158,7 @@ mod imp {
159158
pub type rust_thread = HANDLE;
160159
pub type rust_thread_return = DWORD;
161160

162-
pub unsafe fn create(stack: uint, p: Box<proc():Send>) -> rust_thread {
161+
pub unsafe fn create(stack: uint, p: Box<proc():Send>, detach: bool) -> Option<rust_thread> {
163162
let arg: *mut libc::c_void = mem::transmute(p);
164163
// FIXME On UNIX, we guard against stack sizes that are too small but
165164
// that's because pthreads enforces that stacks are at least
@@ -179,15 +178,20 @@ mod imp {
179178
let _p: Box<proc():Send> = mem::transmute(arg);
180179
fail!("failed to spawn native thread: {}", ret);
181180
}
182-
return ret;
181+
if detach {
182+
detach(ret);
183+
return None;
184+
} else {
185+
return Some(ret);
186+
}
183187
}
184188

185189
pub unsafe fn join(native: rust_thread) {
186190
use libc::consts::os::extra::INFINITE;
187191
WaitForSingleObject(native, INFINITE);
188192
}
189193

190-
pub unsafe fn detach(native: rust_thread) {
194+
unsafe fn detach(native: rust_thread) {
191195
assert!(libc::CloseHandle(native) != 0);
192196
}
193197

@@ -219,20 +223,26 @@ mod imp {
219223
use core::cmp;
220224
use core::mem;
221225
use core::ptr;
222-
use libc::consts::os::posix01::{PTHREAD_CREATE_JOINABLE, PTHREAD_STACK_MIN};
226+
use libc::consts::os::posix01::{PTHREAD_CREATE_JOINABLE, PTHREAD_CREATE_DETACHED,
227+
PTHREAD_STACK_MIN};
223228
use libc;
224229

225230
use stack::RED_ZONE;
226231

227232
pub type rust_thread = libc::pthread_t;
228233
pub type rust_thread_return = *mut u8;
229234

230-
pub unsafe fn create(stack: uint, p: Box<proc():Send>) -> rust_thread {
235+
pub unsafe fn create(stack: uint, p: Box<proc():Send>, create_detached: bool) -> Option<rust_thread> {
231236
let mut native: libc::pthread_t = mem::zeroed();
232237
let mut attr: libc::pthread_attr_t = mem::zeroed();
233238
assert_eq!(pthread_attr_init(&mut attr), 0);
234-
assert_eq!(pthread_attr_setdetachstate(&mut attr,
235-
PTHREAD_CREATE_JOINABLE), 0);
239+
if !create_detached {
240+
assert_eq!(pthread_attr_setdetachstate(&mut attr,
241+
PTHREAD_CREATE_JOINABLE), 0);
242+
} else {
243+
assert_eq!(pthread_attr_setdetachstate(&mut attr,
244+
PTHREAD_CREATE_DETACHED), 0);
245+
}
236246

237247
// Reserve room for the red zone, the runtime's stack of last resort.
238248
let stack_size = cmp::max(stack, RED_ZONE + min_stack_size(&attr) as uint);
@@ -264,17 +274,17 @@ mod imp {
264274
let _p: Box<proc():Send> = mem::transmute(arg);
265275
fail!("failed to spawn native thread: {}", ret);
266276
}
267-
native
277+
if create_detached {
278+
return None;
279+
} else {
280+
return Some(native);
281+
}
268282
}
269283

270284
pub unsafe fn join(native: rust_thread) {
271285
assert_eq!(pthread_join(native, ptr::mut_null()), 0);
272286
}
273287

274-
pub unsafe fn detach(native: rust_thread) {
275-
assert_eq!(pthread_detach(native), 0);
276-
}
277-
278288
pub unsafe fn yield_now() { assert_eq!(sched_yield(), 0); }
279289
// glibc >= 2.15 has a __pthread_get_minstack() function that returns
280290
// PTHREAD_STACK_MIN plus however many bytes are needed for thread-local
@@ -320,7 +330,6 @@ mod imp {
320330
stack_size: libc::size_t) -> libc::c_int;
321331
fn pthread_attr_setdetachstate(attr: *mut libc::pthread_attr_t,
322332
state: libc::c_int) -> libc::c_int;
323-
fn pthread_detach(thread: libc::pthread_t) -> libc::c_int;
324333
fn sched_yield() -> libc::c_int;
325334
}
326335
}

0 commit comments

Comments
 (0)