From: Brian Anderson Date: Tue, 30 Apr 2013 01:28:01 +0000 (-0700) Subject: Merge remote-tracking branch 'brson/io' X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=4a4646fd54a85f78512e5f2d1d2cd253954d1ea4;p=rust.git Merge remote-tracking branch 'brson/io' Conflicts: src/libcore/task/local_data_priv.rs --- 4a4646fd54a85f78512e5f2d1d2cd253954d1ea4 diff --cc src/libcore/rt/sched/mod.rs index 28946281628,f7b9bd82668..d7543ae138c --- a/src/libcore/rt/sched/mod.rs +++ b/src/libcore/rt/sched/mod.rs @@@ -349,9 -359,11 +359,12 @@@ pub impl Task unsafe { let sched = local_sched::unsafe_borrow(); sched.run_cleanup_job(); - } - start(); + let sched = local_sched::unsafe_borrow(); + let task = sched.current_task.get_mut_ref(); - task.local_services.run(start); ++ // FIXME #6141: shouldn't neet to put `start()` in another closure ++ task.local_services.run(||start()); + } let sched = local_sched::take(); sched.terminate_current_task(); diff --cc src/libcore/sys.rs index 8cad0a22886,7c2d9dd46c3..215fc95f8c7 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@@ -165,49 -166,32 +166,67 @@@ pub fn log_str(t: &T) -> ~str } } -/** Initiate task failure */ +/// Trait for initiating task failure. +pub trait FailWithCause { + /// Fail the current task, taking ownership of `cause` + fn fail_with(cause: Self, file: &'static str, line: uint) -> !; +} + +impl FailWithCause for ~str { + fn fail_with(cause: ~str, file: &'static str, line: uint) -> ! { + do str::as_buf(cause) |msg_buf, _msg_len| { + do str::as_buf(file) |file_buf, _file_len| { + unsafe { + let msg_buf = cast::transmute(msg_buf); + let file_buf = cast::transmute(file_buf); + begin_unwind_(msg_buf, file_buf, line as libc::size_t) + } + } + } + } +} + +impl FailWithCause for &'static str { + fn fail_with(cause: &'static str, file: &'static str, line: uint) -> ! { + do str::as_buf(cause) |msg_buf, _msg_len| { + do str::as_buf(file) |file_buf, _file_len| { + unsafe { + let msg_buf = cast::transmute(msg_buf); + let file_buf = cast::transmute(file_buf); + begin_unwind_(msg_buf, file_buf, line as libc::size_t) + } + } + } + } +} + +// NOTE: remove function after snapshot +#[cfg(stage0)] pub fn begin_unwind(msg: ~str, file: ~str, line: uint) -> ! { - do str::as_buf(msg) |msg_buf, _msg_len| { - do str::as_buf(file) |file_buf, _file_len| { + + use rt::{context, OldTaskContext}; + use rt::local_services::unsafe_borrow_local_services; + + match context() { + OldTaskContext => { + do str::as_buf(msg) |msg_buf, _msg_len| { + do str::as_buf(file) |file_buf, _file_len| { + unsafe { + let msg_buf = cast::transmute(msg_buf); + let file_buf = cast::transmute(file_buf); + begin_unwind_(msg_buf, file_buf, line as libc::size_t) + } + } + } + } + _ => { + gc::cleanup_stack_for_failure(); unsafe { - let msg_buf = cast::transmute(msg_buf); - let file_buf = cast::transmute(file_buf); - begin_unwind_(msg_buf, file_buf, line as libc::size_t) + let local_services = unsafe_borrow_local_services(); + match local_services.unwinder { + Some(ref mut unwinder) => unwinder.begin_unwind(), + None => abort!("failure without unwinder. aborting process") + } } } } diff --cc src/libcore/task/local_data_priv.rs index 67bc3adeb41,fdf1fa2a532..10a40887e57 --- a/src/libcore/task/local_data_priv.rs +++ b/src/libcore/task/local_data_priv.rs @@@ -59,8 -94,10 +94,8 @@@ unsafe fn get_task_local_map(task: *rus let map_ptr = rt::rust_get_task_local_data(task); if map_ptr.is_null() { let map: TaskLocalMap = @mut ~[]; - // Use reinterpret_cast -- transmute would take map away from us also. - rt::rust_set_task_local_data( - task, cast::transmute(map)); + rt::rust_set_task_local_data(task, cast::transmute(map)); - rt::rust_task_local_data_atexit(task, cleanup_task_local_map); + rt::rust_task_local_data_atexit(task, cleanup_task_local_map_extern_cb); // Also need to reference it an extra time to keep it for now. let nonmut = cast::transmute::]>(map); @@@ -75,10 -112,33 +110,31 @@@ } } + unsafe fn get_newsched_local_map(local: *mut LocalStorage) -> TaskLocalMap { + match &mut *local { + &LocalStorage(map_ptr, Some(_)) => { + assert!(map_ptr.is_not_null()); + let map = cast::transmute(map_ptr); + let nonmut = cast::transmute::]>(map); + cast::bump_box_refcount(nonmut); + return map; + } + &LocalStorage(ref mut map_ptr, ref mut at_exit) => { + assert!((*map_ptr).is_null()); + let map: TaskLocalMap = @mut ~[]; + *map_ptr = cast::transmute(map); + let at_exit_fn: ~fn(*libc::c_void) = |p|cleanup_task_local_map(p); + *at_exit = Some(at_exit_fn); + return map; + } + } + } + -unsafe fn key_to_key_value( - key: LocalDataKey) -> *libc::c_void { - +unsafe fn key_to_key_value(key: LocalDataKey) -> *libc::c_void { // Keys are closures, which are (fnptr,envptr) pairs. Use fnptr. // Use reintepret_cast -- transmute would leak (forget) the closure. - let pair: (*libc::c_void, *libc::c_void) = cast::transmute(key); + let pair: (*libc::c_void, *libc::c_void) = cast::transmute_copy(&key); pair.first() } diff --cc src/libcore/unstable/lang.rs index 611862a79e7,cb3f399f591..d9870f52289 --- a/src/libcore/unstable/lang.rs +++ b/src/libcore/unstable/lang.rs @@@ -88,7 -90,8 +90,8 @@@ pub unsafe fn exchange_free(ptr: *c_cha #[lang="malloc"] #[inline(always)] + #[cfg(stage0)] // For some reason this isn't working on windows in stage0 -pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char { +pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char { return rustrt::rust_upcall_malloc_noswitch(td, size); }