From 54e92c88be755ae2275aa304b4cb2c44ee0eebe1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 10 Jun 2013 13:00:38 -0700 Subject: [PATCH 1/2] Rename all files with the 'rc' extension --- Makefile.in | 16 ++++++++-------- mk/tools.mk | 16 ++++++++-------- .../{compiletest.rc => compiletest.rs} | 0 src/libextra/{std.rc => extra.rs} | 0 src/libfuzzer/{fuzzer.rc => fuzzer.rs} | 0 src/librust/{rust.rc => rust.rs} | 0 src/librustc/{rustc.rc => rustc.rs} | 0 src/librustdoc/{rustdoc.rc => rustdoc.rs} | 0 src/librusti/{rusti.rc => rusti.rs} | 0 src/librustpkg/{rustpkg.rc => rustpkg.rs} | 0 src/libstd/{core.rc => std.rs} | 0 src/libsyntax/{syntax.rc => syntax.rs} | 0 12 files changed, 16 insertions(+), 16 deletions(-) rename src/compiletest/{compiletest.rc => compiletest.rs} (100%) rename src/libextra/{std.rc => extra.rs} (100%) rename src/libfuzzer/{fuzzer.rc => fuzzer.rs} (100%) rename src/librust/{rust.rc => rust.rs} (100%) rename src/librustc/{rustc.rc => rustc.rs} (100%) rename src/librustdoc/{rustdoc.rc => rustdoc.rs} (100%) rename src/librusti/{rusti.rc => rusti.rs} (100%) rename src/librustpkg/{rustpkg.rc => rustpkg.rs} (100%) rename src/libstd/{core.rc => std.rs} (100%) rename src/libsyntax/{syntax.rc => syntax.rs} (100%) diff --git a/Makefile.in b/Makefile.in index ca82f29602278..0fab74c68100f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -242,29 +242,29 @@ $(foreach target,$(CFG_TARGET_TRIPLES),\ # Standard library variables ###################################################################### -STDLIB_CRATE := $(S)src/libstd/core.rc +STDLIB_CRATE := $(S)src/libstd/std.rs STDLIB_INPUTS := $(wildcard $(addprefix $(S)src/libstd/, \ - core.rc *.rs */*.rs */*/*rs */*/*/*rs)) + *.rs */*.rs */*/*rs */*/*/*rs)) ###################################################################### # Extra library variables ###################################################################### -EXTRALIB_CRATE := $(S)src/libextra/std.rc +EXTRALIB_CRATE := $(S)src/libextra/extra.rs EXTRALIB_INPUTS := $(wildcard $(addprefix $(S)src/libextra/, \ - std.rc *.rs */*.rs)) + *.rs */*.rs)) ###################################################################### # rustc crate variables ###################################################################### -COMPILER_CRATE := $(S)src/librustc/rustc.rc +COMPILER_CRATE := $(S)src/librustc/rustc.rs COMPILER_INPUTS := $(wildcard $(addprefix $(S)src/librustc/, \ - rustc.rc *.rs */*.rs */*/*.rs */*/*/*.rs)) + *.rs */*.rs */*/*.rs */*/*/*.rs)) -LIBSYNTAX_CRATE := $(S)src/libsyntax/syntax.rc +LIBSYNTAX_CRATE := $(S)src/libsyntax/syntax.rs LIBSYNTAX_INPUTS := $(wildcard $(addprefix $(S)src/libsyntax/, \ - syntax.rc *.rs */*.rs */*/*.rs)) + *.rs */*.rs */*/*.rs)) DRIVER_CRATE := $(S)src/driver/driver.rs diff --git a/mk/tools.mk b/mk/tools.mk index 018da2a640169..b02e9eda9e5d3 100644 --- a/mk/tools.mk +++ b/mk/tools.mk @@ -11,27 +11,27 @@ # Rules for non-core tools built with the compiler, both for target # and host architectures -FUZZER_LIB := $(S)src/libfuzzer/fuzzer.rc +FUZZER_LIB := $(S)src/libfuzzer/fuzzer.rs FUZZER_INPUTS := $(wildcard $(addprefix $(S)src/libfuzzer/, *.rs)) # The test runner that runs the cfail/rfail/rpass and bxench tests -COMPILETEST_CRATE := $(S)src/compiletest/compiletest.rc -COMPILETEST_INPUTS := $(wildcard $(S)src/compiletest/*rs) +COMPILETEST_CRATE := $(S)src/compiletest/compiletest.rs +COMPILETEST_INPUTS := $(wildcard $(S)src/compiletest/*.rs) # Rustpkg, the package manager and build system -RUSTPKG_LIB := $(S)src/librustpkg/rustpkg.rc -RUSTPKG_INPUTS := $(wildcard $(S)src/librustpkg/*rs) +RUSTPKG_LIB := $(S)src/librustpkg/rustpkg.rs +RUSTPKG_INPUTS := $(wildcard $(S)src/librustpkg/*.rs) # Rustdoc, the documentation tool -RUSTDOC_LIB := $(S)src/librustdoc/rustdoc.rc +RUSTDOC_LIB := $(S)src/librustdoc/rustdoc.rs RUSTDOC_INPUTS := $(wildcard $(S)src/librustdoc/*.rs) # Rusti, the JIT REPL -RUSTI_LIB := $(S)src/librusti/rusti.rc +RUSTI_LIB := $(S)src/librusti/rusti.rs RUSTI_INPUTS := $(wildcard $(S)src/librusti/*.rs) # Rust, the convenience tool -RUST_LIB := $(S)src/librust/rust.rc +RUST_LIB := $(S)src/librust/rust.rs RUST_INPUTS := $(wildcard $(S)src/librust/*.rs) # FIXME: These are only built for the host arch. Eventually we'll diff --git a/src/compiletest/compiletest.rc b/src/compiletest/compiletest.rs similarity index 100% rename from src/compiletest/compiletest.rc rename to src/compiletest/compiletest.rs diff --git a/src/libextra/std.rc b/src/libextra/extra.rs similarity index 100% rename from src/libextra/std.rc rename to src/libextra/extra.rs diff --git a/src/libfuzzer/fuzzer.rc b/src/libfuzzer/fuzzer.rs similarity index 100% rename from src/libfuzzer/fuzzer.rc rename to src/libfuzzer/fuzzer.rs diff --git a/src/librust/rust.rc b/src/librust/rust.rs similarity index 100% rename from src/librust/rust.rc rename to src/librust/rust.rs diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rs similarity index 100% rename from src/librustc/rustc.rc rename to src/librustc/rustc.rs diff --git a/src/librustdoc/rustdoc.rc b/src/librustdoc/rustdoc.rs similarity index 100% rename from src/librustdoc/rustdoc.rc rename to src/librustdoc/rustdoc.rs diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rs similarity index 100% rename from src/librusti/rusti.rc rename to src/librusti/rusti.rs diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rs similarity index 100% rename from src/librustpkg/rustpkg.rc rename to src/librustpkg/rustpkg.rs diff --git a/src/libstd/core.rc b/src/libstd/std.rs similarity index 100% rename from src/libstd/core.rc rename to src/libstd/std.rs diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rs similarity index 100% rename from src/libsyntax/syntax.rc rename to src/libsyntax/syntax.rs From d2037d34e56e25a07dfc5f3fb961e13e337b8903 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 8 Jun 2013 21:56:13 -0700 Subject: [PATCH 2/2] Deny common lints by default for lib{std,extra} --- Makefile.in | 10 + mk/target.mk | 4 +- src/libextra/arc.rs | 16 +- src/libextra/c_vec.rs | 2 +- src/libextra/extra.rs | 4 +- src/libextra/net_tcp.rs | 288 +++++++++++++++++++++++ src/libextra/smallintmap.rs | 5 - src/libextra/sync.rs | 73 ++++++ src/libextra/terminfo/parser/compiled.rs | 1 - src/libextra/uv_global_loop.rs | 34 ++- src/libstd/comm.rs | 22 ++ src/libstd/hashmap.rs | 2 +- src/libstd/libc.rs | 2 +- src/libstd/local_data.rs | 24 +- src/libstd/os.rs | 127 +++++----- src/libstd/pipes.rs | 2 +- src/libstd/rt/message_queue.rs | 17 ++ src/libstd/rt/thread_local_storage.rs | 4 +- src/libstd/rt/uv/mod.rs | 2 - src/libstd/rt/uv/timer.rs | 4 +- src/libstd/rt/work_queue.rs | 33 +++ src/libstd/run.rs | 5 +- src/libstd/std.rs | 3 - src/libstd/task/mod.rs | 14 +- src/libstd/task/spawn.rs | 16 +- src/libstd/unstable/global.rs | 40 ++++ src/libstd/unstable/lang.rs | 36 +++ 27 files changed, 643 insertions(+), 147 deletions(-) diff --git a/Makefile.in b/Makefile.in index 0fab74c68100f..929c2954aecf2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -127,6 +127,16 @@ ifndef DEBUG_BORROWS RUSTFLAGS_STAGE2 += -Z no-debug-borrows endif +# The standard libraries should be held up to a higher standard than any old +# code, make sure that these common warnings are denied by default. These can +# be overridden during development temporarily. +RUSTDENYFLAGS := -D dead-assignment -D unnecessary-allocation \ + -D unreachable-code -D unused-imports -D unused-mut \ + -D unused-unsafe -D unused-variable -D missing-doc \ + -D non-camel-case-types +DENYFLAGS_STAGE1 := $(RUSTDENYFLAGS) +DENYFLAGS_STAGE2 := $(RUSTDENYFLAGS) + # platform-specific auto-configuration include $(CFG_SRC_DIR)mk/platform.mk diff --git a/mk/target.mk b/mk/target.mk index 737b3b82c00de..a66f66dc55cdb 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -39,7 +39,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)): \ $$(TSREQ$(1)_T_$(2)_H_$(3)) \ | $$(TLIB$(1)_T_$(2)_H_$(3))/ @$$(call E, compile_and_link: $$@) - $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< && touch $$@ + $$(STAGE$(1)_T_$(2)_H_$(3)) $$(DENYFLAGS_STAGE$(1)) -o $$@ $$< && touch $$@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)): \ $$(EXTRALIB_CRATE) $$(EXTRALIB_INPUTS) \ @@ -47,7 +47,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)): \ $$(TSREQ$(1)_T_$(2)_H_$(3)) \ | $$(TLIB$(1)_T_$(2)_H_$(3))/ @$$(call E, compile_and_link: $$@) - $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< && touch $$@ + $$(STAGE$(1)_T_$(2)_H_$(3)) $$(DENYFLAGS_STAGE$(1)) -o $$@ $$< && touch $$@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(3)): \ $$(LIBSYNTAX_CRATE) $$(LIBSYNTAX_INPUTS) \ diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index 1b6b656e398a4..d71be2501a752 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -200,15 +200,13 @@ impl MutexARC { */ #[inline(always)] pub unsafe fn access(&self, blk: &fn(x: &mut T) -> U) -> U { - unsafe { - let state = self.x.get(); - // Borrowck would complain about this if the function were - // not already unsafe. See borrow_rwlock, far below. - do (&(*state).lock).lock { - check_poison(true, (*state).failed); - let _z = PoisonOnFail(&mut (*state).failed); - blk(&mut (*state).data) - } + let state = self.x.get(); + // Borrowck would complain about this if the function were + // not already unsafe. See borrow_rwlock, far below. + do (&(*state).lock).lock { + check_poison(true, (*state).failed); + let _z = PoisonOnFail(&mut (*state).failed); + blk(&mut (*state).data) } } diff --git a/src/libextra/c_vec.rs b/src/libextra/c_vec.rs index 7cc7b659ed9dd..d39c2eac77fb1 100644 --- a/src/libextra/c_vec.rs +++ b/src/libextra/c_vec.rs @@ -160,7 +160,7 @@ mod tests { assert!(mem as int != 0); return c_vec_with_dtor(mem as *mut u8, n as uint, - || unsafe { free(mem) }); + || { free(mem) }); } } diff --git a/src/libextra/extra.rs b/src/libextra/extra.rs index 83c0bb516b436..fb795da8ffc9a 100644 --- a/src/libextra/extra.rs +++ b/src/libextra/extra.rs @@ -26,9 +26,6 @@ not required in or otherwise suitable for the core library. #[license = "MIT/ASL2"]; #[crate_type = "lib"]; -#[deny(non_camel_case_types)]; -#[deny(missing_doc)]; - // NOTE: remove these two attributes after the next snapshot #[no_core]; // for stage0 #[allow(unrecognized_lint)]; // otherwise stage0 is seriously ugly @@ -37,6 +34,7 @@ not required in or otherwise suitable for the core library. extern mod core(name = "std", vers = "0.7-pre"); +#[cfg(stage0)] use core::{str, unstable}; use core::str::{StrSlice, OwnedStr}; diff --git a/src/libextra/net_tcp.rs b/src/libextra/net_tcp.rs index d95807f2b91c4..70c275bc5f45e 100644 --- a/src/libextra/net_tcp.rs +++ b/src/libextra/net_tcp.rs @@ -146,6 +146,7 @@ pub enum TcpConnectErrData { * the remote host. In the event of failure, a * `net::tcp::TcpConnectErrData` instance will be returned */ +#[cfg(stage0)] pub fn connect(input_ip: ip::IpAddr, port: uint, iotask: &IoTask) -> result::Result { @@ -289,6 +290,148 @@ pub fn connect(input_ip: ip::IpAddr, port: uint, } } } +#[cfg(not(stage0))] +pub fn connect(input_ip: ip::IpAddr, port: uint, + iotask: &IoTask) + -> result::Result { + unsafe { + let (result_po, result_ch) = stream::(); + let result_ch = SharedChan::new(result_ch); + let (closed_signal_po, closed_signal_ch) = stream::<()>(); + let closed_signal_ch = SharedChan::new(closed_signal_ch); + let conn_data = ConnectReqData { + result_ch: result_ch, + closed_signal_ch: closed_signal_ch + }; + let conn_data_ptr: *ConnectReqData = &conn_data; + let (reader_po, reader_ch) = stream::>(); + let reader_ch = SharedChan::new(reader_ch); + let stream_handle_ptr = malloc_uv_tcp_t(); + *(stream_handle_ptr as *mut uv::ll::uv_tcp_t) = uv::ll::tcp_t(); + let socket_data = @TcpSocketData { + reader_po: @reader_po, + reader_ch: reader_ch, + stream_handle_ptr: stream_handle_ptr, + connect_req: uv::ll::connect_t(), + write_req: uv::ll::write_t(), + ipv6: match input_ip { + ip::Ipv4(_) => { false } + ip::Ipv6(_) => { true } + }, + iotask: iotask.clone() + }; + let socket_data_ptr: *TcpSocketData = &*socket_data; + // get an unsafe representation of our stream_handle_ptr that + // we can send into the interact cb to be handled in libuv.. + debug!("stream_handle_ptr outside interact %?", + stream_handle_ptr); + do iotask::interact(iotask) |loop_ptr| { + debug!("in interact cb for tcp client connect.."); + debug!("stream_handle_ptr in interact %?", + stream_handle_ptr); + match uv::ll::tcp_init( loop_ptr, stream_handle_ptr) { + 0i32 => { + debug!("tcp_init successful"); + debug!("dealing w/ ipv4 connection.."); + let connect_req_ptr: *uv::ll::uv_connect_t = + &(*socket_data_ptr).connect_req; + let addr_str = ip::format_addr(&input_ip); + let connect_result = match input_ip { + ip::Ipv4(ref addr) => { + // have to "recreate" the + // sockaddr_in/6 since the ip_addr + // discards the port info.. should + // probably add an additional rust + // type that actually is closer to + // what the libuv API expects (ip str + // + port num) + debug!("addr: %?", addr); + let in_addr = uv::ll::ip4_addr(addr_str, + port as int); + uv::ll::tcp_connect( + connect_req_ptr, + stream_handle_ptr, + &in_addr, + tcp_connect_on_connect_cb) + } + ip::Ipv6(ref addr) => { + debug!("addr: %?", addr); + let in_addr = uv::ll::ip6_addr(addr_str, + port as int); + uv::ll::tcp_connect6( + connect_req_ptr, + stream_handle_ptr, + &in_addr, + tcp_connect_on_connect_cb) + } + }; + match connect_result { + 0i32 => { + debug!("tcp_connect successful: \ + stream %x, + socket data %x", + stream_handle_ptr as uint, + socket_data_ptr as uint); + // reusable data that we'll have for the + // duration.. + uv::ll::set_data_for_uv_handle( + stream_handle_ptr, + socket_data_ptr as + *libc::c_void); + // just so the connect_cb can send the + // outcome.. + uv::ll::set_data_for_req(connect_req_ptr, + conn_data_ptr); + debug!("leaving tcp_connect interact cb..."); + // let tcp_connect_on_connect_cb send on + // the result_ch, now.. + } + _ => { + // immediate connect + // failure.. probably a garbage ip or + // somesuch + let err_data = + uv::ll::get_last_err_data(loop_ptr); + let result_ch = (*conn_data_ptr) + .result_ch.clone(); + result_ch.send(ConnFailure(err_data)); + uv::ll::set_data_for_uv_handle( + stream_handle_ptr, + conn_data_ptr); + uv::ll::close(stream_handle_ptr, + stream_error_close_cb); + } + } + } + _ => { + // failure to create a tcp handle + let err_data = uv::ll::get_last_err_data(loop_ptr); + let result_ch = (*conn_data_ptr).result_ch.clone(); + result_ch.send(ConnFailure(err_data)); + } + } + } + match result_po.recv() { + ConnSuccess => { + debug!("tcp::connect - received success on result_po"); + result::Ok(TcpSocket(socket_data)) + } + ConnFailure(ref err_data) => { + closed_signal_po.recv(); + debug!("tcp::connect - received failure on result_po"); + // still have to free the malloc'd stream handle.. + rustrt::rust_uv_current_kernel_free(stream_handle_ptr + as *libc::c_void); + let tcp_conn_err = match err_data.err_name { + ~"ECONNREFUSED" => ConnectionRefused, + _ => GenericConnectErr(copy err_data.err_name, + copy err_data.err_msg) + }; + result::Err(tcp_conn_err) + } + } + } +} /** * Write binary data to a tcp stream; Blocks until operation completes @@ -1006,6 +1149,7 @@ impl io::Writer for TcpSocketBuf { // INTERNAL API +#[cfg(stage0)] fn tear_down_socket_data(socket_data: @TcpSocketData) { unsafe { let (closed_po, closed_ch) = stream::<()>(); @@ -1033,6 +1177,32 @@ fn tear_down_socket_data(socket_data: @TcpSocketData) { debug!("exiting dtor for tcp_socket"); } } +#[cfg(not(stage0))] +fn tear_down_socket_data(socket_data: @TcpSocketData) { + unsafe { + let (closed_po, closed_ch) = stream::<()>(); + let closed_ch = SharedChan::new(closed_ch); + let close_data = TcpSocketCloseData { + closed_ch: closed_ch + }; + let close_data_ptr: *TcpSocketCloseData = &close_data; + let stream_handle_ptr = (*socket_data).stream_handle_ptr; + do iotask::interact(&(*socket_data).iotask) |loop_ptr| { + debug!( + "interact dtor for tcp_socket stream %? loop %?", + stream_handle_ptr, loop_ptr); + uv::ll::set_data_for_uv_handle(stream_handle_ptr, + close_data_ptr); + uv::ll::close(stream_handle_ptr, tcp_socket_dtor_close_cb); + }; + closed_po.recv(); + //the line below will most likely crash + //log(debug, fmt!("about to free socket_data at %?", socket_data)); + rustrt::rust_uv_current_kernel_free(stream_handle_ptr + as *libc::c_void); + debug!("exiting dtor for tcp_socket"); + } +} // shared implementation for tcp::read fn read_common_impl(socket_data: *TcpSocketData, timeout_msecs: uint) @@ -1077,6 +1247,7 @@ fn read_common_impl(socket_data: *TcpSocketData, timeout_msecs: uint) } // shared impl for read_stop +#[cfg(stage0)] fn read_stop_common_impl(socket_data: *TcpSocketData) -> result::Result<(), TcpErrData> { unsafe { @@ -1105,8 +1276,37 @@ fn read_stop_common_impl(socket_data: *TcpSocketData) -> } } } +// shared impl for read_stop +#[cfg(not(stage0))] +fn read_stop_common_impl(socket_data: *TcpSocketData) -> + result::Result<(), TcpErrData> { + unsafe { + let stream_handle_ptr = (*socket_data).stream_handle_ptr; + let (stop_po, stop_ch) = stream::>(); + do iotask::interact(&(*socket_data).iotask) |loop_ptr| { + debug!("in interact cb for tcp::read_stop"); + match uv::ll::read_stop(stream_handle_ptr + as *uv::ll::uv_stream_t) { + 0i32 => { + debug!("successfully called uv_read_stop"); + stop_ch.send(None); + } + _ => { + debug!("failure in calling uv_read_stop"); + let err_data = uv::ll::get_last_err_data(loop_ptr); + stop_ch.send(Some(err_data.to_tcp_err())); + } + } + } + match stop_po.recv() { + Some(err_data) => Err(err_data), + None => Ok(()) + } + } +} // shared impl for read_start +#[cfg(stage0)] fn read_start_common_impl(socket_data: *TcpSocketData) -> result::Result<@Port< result::Result<~[u8], TcpErrData>>, TcpErrData> { @@ -1143,10 +1343,47 @@ fn read_start_common_impl(socket_data: *TcpSocketData) } } } +// shared impl for read_start +#[cfg(not(stage0))] +fn read_start_common_impl(socket_data: *TcpSocketData) + -> result::Result<@Port< + result::Result<~[u8], TcpErrData>>, TcpErrData> { + unsafe { + let stream_handle_ptr = (*socket_data).stream_handle_ptr; + let (start_po, start_ch) = stream::>(); + debug!("in tcp::read_start before interact loop"); + do iotask::interact(&(*socket_data).iotask) |loop_ptr| { + debug!("in tcp::read_start interact cb %?", + loop_ptr); + match uv::ll::read_start(stream_handle_ptr + as *uv::ll::uv_stream_t, + on_alloc_cb, + on_tcp_read_cb) { + 0i32 => { + debug!("success doing uv_read_start"); + start_ch.send(None); + } + _ => { + debug!("error attempting uv_read_start"); + let err_data = uv::ll::get_last_err_data(loop_ptr); + start_ch.send(Some(err_data)); + } + } + } + match start_po.recv() { + Some(ref err_data) => result::Err( + err_data.to_tcp_err()), + None => { + result::Ok((*socket_data).reader_po) + } + } + } +} // helper to convert a "class" vector of [u8] to a *[uv::ll::uv_buf_t] // shared implementation used by write and write_future +#[cfg(stage0)] fn write_common_impl(socket_data_ptr: *TcpSocketData, raw_write_data: ~[u8]) -> result::Result<(), TcpErrData> { @@ -1198,6 +1435,57 @@ fn write_common_impl(socket_data_ptr: *TcpSocketData, } } } +// shared implementation used by write and write_future +#[cfg(not(stage0))] +fn write_common_impl(socket_data_ptr: *TcpSocketData, + raw_write_data: ~[u8]) + -> result::Result<(), TcpErrData> { + unsafe { + let write_req_ptr: *uv::ll::uv_write_t = + &(*socket_data_ptr).write_req; + let stream_handle_ptr = + (*socket_data_ptr).stream_handle_ptr; + let write_buf_vec = ~[ + uv::ll::buf_init(vec::raw::to_ptr(raw_write_data), + raw_write_data.len()) + ]; + let write_buf_vec_ptr: *~[uv::ll::uv_buf_t] = &write_buf_vec; + let (result_po, result_ch) = stream::(); + let result_ch = SharedChan::new(result_ch); + let write_data = WriteReqData { + result_ch: result_ch + }; + let write_data_ptr: *WriteReqData = &write_data; + do iotask::interact(&(*socket_data_ptr).iotask) |loop_ptr| { + debug!("in interact cb for tcp::write %?", + loop_ptr); + match uv::ll::write(write_req_ptr, + stream_handle_ptr, + write_buf_vec_ptr, + tcp_write_complete_cb) { + 0i32 => { + debug!("uv_write() invoked successfully"); + uv::ll::set_data_for_req(write_req_ptr, + write_data_ptr); + } + _ => { + debug!("error invoking uv_write()"); + let err_data = uv::ll::get_last_err_data(loop_ptr); + let result_ch = (*write_data_ptr).result_ch.clone(); + result_ch.send(TcpWriteError(err_data.to_tcp_err())); + } + } + } + // FIXME (#2656): Instead of passing unsafe pointers to local data, + // and waiting here for the write to complete, we should transfer + // ownership of everything to the I/O task and let it deal with the + // aftermath, so we don't have to sit here blocking. + match result_po.recv() { + TcpWriteSuccess => Ok(()), + TcpWriteError(err_data) => Err(err_data) + } + } +} enum TcpNewConnection { NewTcpConn(*uv::ll::uv_tcp_t) diff --git a/src/libextra/smallintmap.rs b/src/libextra/smallintmap.rs index 7f566bc16e732..d63e1c4516ffb 100644 --- a/src/libextra/smallintmap.rs +++ b/src/libextra/smallintmap.rs @@ -294,11 +294,6 @@ mod tests { use super::SmallIntMap; - use core::local_data; - use core::rand; - use core::uint; - use core::vec; - #[test] fn test_find_mut() { let mut m = SmallIntMap::new(); diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index 8bbe0afa704e1..6bb505d4f3600 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -99,6 +99,40 @@ fn new_sem_and_signal(count: int, num_condvars: uint) } #[doc(hidden)] +#[cfg(stage0)] +impl Sem { + pub fn acquire(&self) { + let mut waiter_nobe = None; + do (**self).with |state| { + state.count -= 1; + if state.count < 0 { + // Create waiter nobe. + let (WaitEnd, SignalEnd) = comm::oneshot(); + // Tell outer scope we need to block. + waiter_nobe = Some(WaitEnd); + // Enqueue ourself. + state.waiters.tail.send(SignalEnd); + } + } + // Uncomment if you wish to test for sem races. Not valgrind-friendly. + /* for 1000.times { task::yield(); } */ + // Need to wait outside the exclusive. + if waiter_nobe.is_some() { + let _ = comm::recv_one(waiter_nobe.unwrap()); + } + } + + pub fn release(&self) { + do (**self).with |state| { + state.count += 1; + if state.count <= 0 { + signal_waitqueue(&state.waiters); + } + } + } +} +#[doc(hidden)] +#[cfg(not(stage0))] impl Sem { pub fn acquire(&self) { unsafe { @@ -289,6 +323,23 @@ impl<'self> Condvar<'self> { pub fn signal(&self) -> bool { self.signal_on(0) } /// As signal, but with a specified condvar_id. See wait_on. + #[cfg(stage0)] + pub fn signal_on(&self, condvar_id: uint) -> bool { + let mut out_of_bounds = None; + let mut result = false; + do (**self.sem).with |state| { + if condvar_id < state.blocked.len() { + result = signal_waitqueue(&state.blocked[condvar_id]); + } else { + out_of_bounds = Some(state.blocked.len()); + } + } + do check_cvar_bounds(out_of_bounds, condvar_id, "cond.signal_on()") { + result + } + } + /// As signal, but with a specified condvar_id. See wait_on. + #[cfg(not(stage0))] pub fn signal_on(&self, condvar_id: uint) -> bool { unsafe { let mut out_of_bounds = None; @@ -310,6 +361,28 @@ impl<'self> Condvar<'self> { pub fn broadcast(&self) -> uint { self.broadcast_on(0) } /// As broadcast, but with a specified condvar_id. See wait_on. + #[cfg(stage0)] + pub fn broadcast_on(&self, condvar_id: uint) -> uint { + let mut out_of_bounds = None; + let mut queue = None; + do (**self.sem).with |state| { + if condvar_id < state.blocked.len() { + // To avoid :broadcast_heavy, we make a new waitqueue, + // swap it out with the old one, and broadcast on the + // old one outside of the little-lock. + queue = Some(util::replace(&mut state.blocked[condvar_id], + new_waitqueue())); + } else { + out_of_bounds = Some(state.blocked.len()); + } + } + do check_cvar_bounds(out_of_bounds, condvar_id, "cond.signal_on()") { + let queue = queue.swap_unwrap(); + broadcast_waitqueue(&queue) + } + } + /// As broadcast, but with a specified condvar_id. See wait_on. + #[cfg(not(stage0))] pub fn broadcast_on(&self, condvar_id: uint) -> uint { let mut out_of_bounds = None; let mut queue = None; diff --git a/src/libextra/terminfo/parser/compiled.rs b/src/libextra/terminfo/parser/compiled.rs index 690596e6248e9..c8c00ec71a7b6 100644 --- a/src/libextra/terminfo/parser/compiled.rs +++ b/src/libextra/terminfo/parser/compiled.rs @@ -314,7 +314,6 @@ pub fn parse(file: @Reader, longnames: bool) -> Result<~TermInfo, ~str> { #[cfg(test)] mod test { use super::*; - use p = core::path::Path; #[test] fn test_veclens() { diff --git a/src/libextra/uv_global_loop.rs b/src/libextra/uv_global_loop.rs index 286863bef641d..f1dde1b8cb41d 100644 --- a/src/libextra/uv_global_loop.rs +++ b/src/libextra/uv_global_loop.rs @@ -150,9 +150,7 @@ mod test { let hl_loop = &get_gl(); do iotask::interact(hl_loop) |_loop_ptr| { debug!(~"closing timer"); - unsafe { - ll::close(timer_ptr, simple_timer_close_cb); - } + ll::close(timer_ptr, simple_timer_close_cb); debug!(~"about to deref exit_ch_ptr"); debug!(~"after msg sent on deref'd exit_ch"); }; @@ -169,24 +167,22 @@ mod test { let timer_handle = ll::timer_t(); let timer_ptr: *ll::uv_timer_t = &timer_handle; do iotask::interact(iotask) |loop_ptr| { - unsafe { - debug!(~"user code inside interact loop!!!"); - let init_status = ll::timer_init(loop_ptr, timer_ptr); - if(init_status == 0i32) { - ll::set_data_for_uv_handle( - timer_ptr as *libc::c_void, - exit_ch_ptr); - let start_status = ll::timer_start(timer_ptr, - simple_timer_cb, - 1u, 0u); - if(start_status != 0i32) { - fail!("failure on ll::timer_start()"); - } - } - else { - fail!("failure on ll::timer_init()"); + debug!(~"user code inside interact loop!!!"); + let init_status = ll::timer_init(loop_ptr, timer_ptr); + if(init_status == 0i32) { + ll::set_data_for_uv_handle( + timer_ptr as *libc::c_void, + exit_ch_ptr); + let start_status = ll::timer_start(timer_ptr, + simple_timer_cb, + 1u, 0u); + if(start_status != 0i32) { + fail!("failure on ll::timer_start()"); } } + else { + fail!("failure on ll::timer_init()"); + } }; exit_po.recv(); debug!( diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs index f0c353c8d62b6..8b8c9b82e1c68 100644 --- a/src/libstd/comm.rs +++ b/src/libstd/comm.rs @@ -236,6 +236,17 @@ impl SharedChan { } } +#[cfg(stage0)] +impl GenericChan for SharedChan { + fn send(&self, x: T) { + let mut xx = Some(x); + do self.ch.with_imm |chan| { + let x = replace(&mut xx, None); + chan.send(x.unwrap()) + } + } +} +#[cfg(not(stage0))] impl GenericChan for SharedChan { fn send(&self, x: T) { unsafe { @@ -248,6 +259,17 @@ impl GenericChan for SharedChan { } } +#[cfg(stage0)] +impl GenericSmartChan for SharedChan { + fn try_send(&self, x: T) -> bool { + let mut xx = Some(x); + do self.ch.with_imm |chan| { + let x = replace(&mut xx, None); + chan.try_send(x.unwrap()) + } + } +} +#[cfg(not(stage0))] impl GenericSmartChan for SharedChan { fn try_send(&self, x: T) -> bool { unsafe { diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index c0cc92723ba4d..003de360a2dcc 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -20,7 +20,7 @@ use cmp::{Eq, Equiv}; use hash::Hash; use old_iter::BaseIter; use old_iter; -use iterator::{Iterator, IteratorUtil}; +use iterator::IteratorUtil; use option::{None, Option, Some}; use rand::RngUtil; use rand; diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index 26205c930f0ca..d840b70c742a8 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -518,7 +518,7 @@ pub mod types { pub mod os { pub mod common { pub mod posix01 { - use libc::types::os::arch::c95::{c_int, c_short}; + use libc::types::os::arch::c95::c_short; use libc::types::os::arch::extra::{int64, time64_t}; use libc::types::os::arch::posix88::{dev_t, ino_t}; use libc::types::os::arch::posix88::mode_t; diff --git a/src/libstd/local_data.rs b/src/libstd/local_data.rs index 82c01c998cf1e..53cb7de0c10fa 100644 --- a/src/libstd/local_data.rs +++ b/src/libstd/local_data.rs @@ -92,14 +92,12 @@ fn test_tls_multitask() { fn my_key(_x: @~str) { } local_data_set(my_key, @~"parent data"); do task::spawn { - unsafe { - // TLS shouldn't carry over. - assert!(local_data_get(my_key).is_none()); - local_data_set(my_key, @~"child data"); - assert!(*(local_data_get(my_key).get()) == - ~"child data"); - // should be cleaned up for us - } + // TLS shouldn't carry over. + assert!(local_data_get(my_key).is_none()); + local_data_set(my_key, @~"child data"); + assert!(*(local_data_get(my_key).get()) == + ~"child data"); + // should be cleaned up for us } // Must work multiple times assert!(*(local_data_get(my_key).get()) == ~"parent data"); @@ -206,12 +204,10 @@ fn test_tls_cleanup_on_failure() { local_data_set(str_key, @~"parent data"); local_data_set(box_key, @@()); do task::spawn { - unsafe { // spawn_linked - local_data_set(str_key, @~"string data"); - local_data_set(box_key, @@()); - local_data_set(int_key, @42); - fail!(); - } + local_data_set(str_key, @~"string data"); + local_data_set(box_key, @@()); + local_data_set(int_key, @42); + fail!(); } // Not quite nondeterministic. local_data_set(int_key, @31337); diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 044b305a0dd9d..04a9b9a9f39cc 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -33,9 +33,8 @@ use io; use iterator::IteratorUtil; use libc; use libc::{c_char, c_void, c_int, size_t}; -use libc::{mode_t, FILE}; +use libc::FILE; use local_data; -use option; use option::{Some, None}; use os; use prelude::*; @@ -181,7 +180,6 @@ pub fn env() -> ~[(~str,~str)] { unsafe { #[cfg(windows)] unsafe fn get_env_pairs() -> ~[~str] { - use libc::types::os::arch::extra::LPTCH; use libc::funcs::extra::kernel32::{ GetEnvironmentStringsA, FreeEnvironmentStringsA @@ -248,10 +246,10 @@ pub fn getenv(n: &str) -> Option<~str> { do with_env_lock { let s = str::as_c_str(n, |s| libc::getenv(s)); if ptr::null::() == cast::transmute(s) { - option::None::<~str> + None::<~str> } else { let s = cast::transmute(s); - option::Some::<~str>(str::raw::from_buf(s)) + Some::<~str>(str::raw::from_buf(s)) } } } @@ -646,9 +644,7 @@ pub fn make_dir(p: &Path, mode: c_int) -> bool { use os::win32::as_utf16_p; // FIXME: turn mode into something useful? #2623 do as_utf16_p(p.to_str()) |buf| { - libc::CreateDirectoryW(buf, unsafe { - cast::transmute(0) - }) + libc::CreateDirectoryW(buf, cast::transmute(0)) != (0 as libc::BOOL) } } @@ -658,7 +654,7 @@ pub fn make_dir(p: &Path, mode: c_int) -> bool { fn mkdir(p: &Path, mode: c_int) -> bool { unsafe { do as_c_charp(p.to_str()) |c| { - libc::mkdir(c, mode as mode_t) == (0 as c_int) + libc::mkdir(c, mode as libc::mode_t) == (0 as c_int) } } } @@ -731,7 +727,6 @@ pub fn list_dir(p: &Path) -> ~[~str] { } #[cfg(windows)] unsafe fn get_list(p: &Path) -> ~[~str] { - use libc::types::os::arch::extra::{LPCTSTR, HANDLE, BOOL}; use libc::consts::os::extra::INVALID_HANDLE_VALUE; use libc::wcslen; use libc::funcs::extra::kernel32::{ @@ -896,78 +891,72 @@ pub fn change_dir_locked(p: &Path, action: &fn()) -> bool { /// Copies a file from one location to another pub fn copy_file(from: &Path, to: &Path) -> bool { - return do_copy_file(from, to); + return unsafe { do_copy_file(from, to) }; #[cfg(windows)] - fn do_copy_file(from: &Path, to: &Path) -> bool { - unsafe { - use os::win32::as_utf16_p; - return do as_utf16_p(from.to_str()) |fromp| { - do as_utf16_p(to.to_str()) |top| { - libc::CopyFileW(fromp, top, (0 as libc::BOOL)) != - (0 as libc::BOOL) - } + unsafe fn do_copy_file(from: &Path, to: &Path) -> bool { + use os::win32::as_utf16_p; + return do as_utf16_p(from.to_str()) |fromp| { + do as_utf16_p(to.to_str()) |top| { + libc::CopyFileW(fromp, top, (0 as libc::BOOL)) != + (0 as libc::BOOL) } } } #[cfg(unix)] - fn do_copy_file(from: &Path, to: &Path) -> bool { - unsafe { - let istream = do as_c_charp(from.to_str()) |fromp| { - do as_c_charp("rb") |modebuf| { - libc::fopen(fromp, modebuf) - } - }; - if istream as uint == 0u { - return false; + unsafe fn do_copy_file(from: &Path, to: &Path) -> bool { + let istream = do as_c_charp(from.to_str()) |fromp| { + do as_c_charp("rb") |modebuf| { + libc::fopen(fromp, modebuf) } - // Preserve permissions - let from_mode = from.get_mode().expect("copy_file: couldn't get permissions \ - for source file"); + }; + if istream as uint == 0u { + return false; + } + // Preserve permissions + let from_mode = from.get_mode().expect("copy_file: couldn't get permissions \ + for source file"); - let ostream = do as_c_charp(to.to_str()) |top| { - do as_c_charp("w+b") |modebuf| { - libc::fopen(top, modebuf) - } - }; - if ostream as uint == 0u { - fclose(istream); - return false; + let ostream = do as_c_charp(to.to_str()) |top| { + do as_c_charp("w+b") |modebuf| { + libc::fopen(top, modebuf) } - let bufsize = 8192u; - let mut buf = vec::with_capacity::(bufsize); - let mut done = false; - let mut ok = true; - while !done { - do vec::as_mut_buf(buf) |b, _sz| { - let nread = libc::fread(b as *mut c_void, 1u as size_t, - bufsize as size_t, - istream); - if nread > 0 as size_t { - if libc::fwrite(b as *c_void, 1u as size_t, nread, - ostream) != nread { - ok = false; - done = true; - } - } else { + }; + if ostream as uint == 0u { + fclose(istream); + return false; + } + let bufsize = 8192u; + let mut buf = vec::with_capacity::(bufsize); + let mut done = false; + let mut ok = true; + while !done { + do vec::as_mut_buf(buf) |b, _sz| { + let nread = libc::fread(b as *mut c_void, 1u as size_t, + bufsize as size_t, + istream); + if nread > 0 as size_t { + if libc::fwrite(b as *c_void, 1u as size_t, nread, + ostream) != nread { + ok = false; done = true; } + } else { + done = true; } - } - fclose(istream); - fclose(ostream); - - // Give the new file the old file's permissions - unsafe { - if do str::as_c_str(to.to_str()) |to_buf| { - libc::chmod(to_buf, from_mode as mode_t) - } != 0 { - return false; // should be a condition... - } - } - return ok; + } + } + fclose(istream); + fclose(ostream); + + // Give the new file the old file's permissions + if do str::as_c_str(to.to_str()) |to_buf| { + libc::chmod(to_buf, from_mode as libc::mode_t) + } != 0 { + return false; // should be a condition... } + return ok; } } @@ -1330,7 +1319,7 @@ pub fn glob(pattern: &str) -> ~[Path] { /// Returns a vector of Path objects that match the given glob pattern #[cfg(target_os = "win32")] -pub fn glob(pattern: &str) -> ~[Path] { +pub fn glob(_pattern: &str) -> ~[Path] { fail!("glob() is unimplemented on Windows") } diff --git a/src/libstd/pipes.rs b/src/libstd/pipes.rs index 012ad0ed80d26..9b59ebe5f3bcf 100644 --- a/src/libstd/pipes.rs +++ b/src/libstd/pipes.rs @@ -103,7 +103,7 @@ use util::replace; static SPIN_COUNT: uint = 0; macro_rules! move_it ( - { $x:expr } => ( unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } ) + { $x:expr } => ( *ptr::to_unsafe_ptr(&($x)) ) ) #[deriving(Eq)] diff --git a/src/libstd/rt/message_queue.rs b/src/libstd/rt/message_queue.rs index 5b60543344de1..4d9a9bac29ada 100644 --- a/src/libstd/rt/message_queue.rs +++ b/src/libstd/rt/message_queue.rs @@ -28,6 +28,12 @@ impl MessageQueue { } } + #[cfg(stage0)] + pub fn push(&mut self, value: T) { + let value = Cell::new(value); + self.queue.with(|q| q.push(value.take()) ); + } + #[cfg(not(stage0))] pub fn push(&mut self, value: T) { unsafe { let value = Cell::new(value); @@ -35,6 +41,17 @@ impl MessageQueue { } } + #[cfg(stage0)] + pub fn pop(&mut self) -> Option { + do self.queue.with |q| { + if !q.is_empty() { + Some(q.shift()) + } else { + None + } + } + } + #[cfg(not(stage0))] pub fn pop(&mut self) -> Option { unsafe { do self.queue.with |q| { diff --git a/src/libstd/rt/thread_local_storage.rs b/src/libstd/rt/thread_local_storage.rs index 7187d2db41cac..5041b559ecbff 100644 --- a/src/libstd/rt/thread_local_storage.rs +++ b/src/libstd/rt/thread_local_storage.rs @@ -60,13 +60,13 @@ pub type Key = DWORD; #[cfg(windows)] pub unsafe fn create(key: &mut Key) { static TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF; - *key = unsafe { TlsAlloc() }; + *key = TlsAlloc(); assert!(*key != TLS_OUT_OF_INDEXES); } #[cfg(windows)] pub unsafe fn set(key: Key, value: *mut c_void) { - unsafe { assert!(0 != TlsSetValue(key, value)) } + assert!(0 != TlsSetValue(key, value)) } #[cfg(windows)] diff --git a/src/libstd/rt/uv/mod.rs b/src/libstd/rt/uv/mod.rs index dd66a76eead91..f50efc079a7c7 100644 --- a/src/libstd/rt/uv/mod.rs +++ b/src/libstd/rt/uv/mod.rs @@ -39,10 +39,8 @@ use option::*; use str::raw::from_c_str; use to_str::ToStr; use ptr::RawPtr; -use libc; use vec; use ptr; -use cast; use str; use libc::{c_void, c_int, size_t, malloc, free}; use cast::transmute; diff --git a/src/libstd/rt/uv/timer.rs b/src/libstd/rt/uv/timer.rs index 5557a58098751..6ee88a50e9c81 100644 --- a/src/libstd/rt/uv/timer.rs +++ b/src/libstd/rt/uv/timer.rs @@ -160,14 +160,14 @@ mod test { let mut timer2 = TimerWatcher::new(&mut loop_); do timer2.start(10, 0) |timer2, _| { - unsafe { *count_ptr += 1; } + *count_ptr += 1; timer2.close(||()); // Restart the original timer let mut timer = timer; do timer.start(10, 0) |timer, _| { - unsafe { *count_ptr += 1; } + *count_ptr += 1; timer.close(||()); } } diff --git a/src/libstd/rt/work_queue.rs b/src/libstd/rt/work_queue.rs index cfffc55a58c80..2ffde95ec5f6a 100644 --- a/src/libstd/rt/work_queue.rs +++ b/src/libstd/rt/work_queue.rs @@ -28,6 +28,12 @@ impl WorkQueue { } } + #[cfg(stage0)] + pub fn push(&mut self, value: T) { + let value = Cell::new(value); + self.queue.with(|q| q.unshift(value.take()) ); + } + #[cfg(not(stage0))] pub fn push(&mut self, value: T) { unsafe { let value = Cell::new(value); @@ -35,6 +41,17 @@ impl WorkQueue { } } + #[cfg(stage0)] + pub fn pop(&mut self) -> Option { + do self.queue.with |q| { + if !q.is_empty() { + Some(q.shift()) + } else { + None + } + } + } + #[cfg(not(stage0))] pub fn pop(&mut self) -> Option { unsafe { do self.queue.with |q| { @@ -47,6 +64,17 @@ impl WorkQueue { } } + #[cfg(stage0)] + pub fn steal(&mut self) -> Option { + do self.queue.with |q| { + if !q.is_empty() { + Some(q.pop()) + } else { + None + } + } + } + #[cfg(not(stage0))] pub fn steal(&mut self) -> Option { unsafe { do self.queue.with |q| { @@ -59,6 +87,11 @@ impl WorkQueue { } } + #[cfg(stage0)] + pub fn is_empty(&self) -> bool { + self.queue.with_imm(|q| q.is_empty() ) + } + #[cfg(not(stage0))] pub fn is_empty(&self) -> bool { unsafe { self.queue.with_imm(|q| q.is_empty() ) diff --git a/src/libstd/run.rs b/src/libstd/run.rs index b204cf6cfb04f..0e9f2d270f877 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -12,11 +12,10 @@ #[allow(missing_doc)]; -use iterator::IteratorUtil; use cast; use comm::{stream, SharedChan, GenericChan, GenericPort}; -use int; use io; +use iterator::IteratorUtil; use libc::{pid_t, c_void, c_int}; use libc; use option::{Some, None}; @@ -465,7 +464,6 @@ fn spawn_process_os(prog: &str, args: &[~str], use libc::funcs::extra::msvcrt::get_osfhandle; use sys; - use uint; unsafe { @@ -638,6 +636,7 @@ fn spawn_process_os(prog: &str, args: &[~str], use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp}; use libc::funcs::bsd44::getdtablesize; + use int; mod rustrt { use libc::c_void; diff --git a/src/libstd/std.rs b/src/libstd/std.rs index a6334cc0c4964..61c6e73b01231 100644 --- a/src/libstd/std.rs +++ b/src/libstd/std.rs @@ -63,9 +63,6 @@ they contained the following prologue: // Don't link to std. We are std. #[no_std]; -#[deny(non_camel_case_types)]; -#[deny(missing_doc)]; - // Make core testable by not duplicating lang items. See #2912 #[cfg(test)] extern mod realstd(name = "std"); #[cfg(test)] pub use kinds = realstd::kinds; diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs index 223afbce091b8..b558b9d53a3cc 100644 --- a/src/libstd/task/mod.rs +++ b/src/libstd/task/mod.rs @@ -934,17 +934,15 @@ fn test_spawn_sched_blocking() { let lock = testrt::rust_dbg_lock_create(); do spawn_sched(SingleThreaded) { - unsafe { - testrt::rust_dbg_lock_lock(lock); + testrt::rust_dbg_lock_lock(lock); - start_ch.send(()); + start_ch.send(()); - // Block the scheduler thread - testrt::rust_dbg_lock_wait(lock); - testrt::rust_dbg_lock_unlock(lock); + // Block the scheduler thread + testrt::rust_dbg_lock_wait(lock); + testrt::rust_dbg_lock_unlock(lock); - fin_ch.send(()); - } + fin_ch.send(()); }; // Wait until the other task has its lock diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 780e9d6d923ed..34a6c4787cfe3 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -92,7 +92,7 @@ use uint; use util; use unstable::sync::{Exclusive, exclusive}; use rt::local::Local; -use iterator::{Iterator, IteratorUtil}; +use iterator::IteratorUtil; #[cfg(test)] use task::default_task_opts; #[cfg(test)] use comm; @@ -162,6 +162,13 @@ struct AncestorList(Option>); // Accessors for taskgroup arcs and ancestor arcs that wrap the unsafety. #[inline(always)] +#[cfg(stage0)] +fn access_group(x: &TaskGroupArc, blk: &fn(TaskGroupInner) -> U) -> U { + x.with(blk) +} +// Accessors for taskgroup arcs and ancestor arcs that wrap the unsafety. +#[inline(always)] +#[cfg(not(stage0))] fn access_group(x: &TaskGroupArc, blk: &fn(TaskGroupInner) -> U) -> U { unsafe { x.with(blk) @@ -169,6 +176,13 @@ fn access_group(x: &TaskGroupArc, blk: &fn(TaskGroupInner) -> U) -> U { } #[inline(always)] +#[cfg(stage0)] +fn access_ancestors(x: &Exclusive, + blk: &fn(x: &mut AncestorNode) -> U) -> U { + x.with(blk) +} +#[inline(always)] +#[cfg(not(stage0))] fn access_ancestors(x: &Exclusive, blk: &fn(x: &mut AncestorNode) -> U) -> U { unsafe { diff --git a/src/libstd/unstable/global.rs b/src/libstd/unstable/global.rs index 96549a83a8cf3..01621433521a2 100644 --- a/src/libstd/unstable/global.rs +++ b/src/libstd/unstable/global.rs @@ -85,6 +85,7 @@ unsafe fn global_data_modify( global_data_modify_(key_ptr(key), op) } +#[cfg(stage0)] unsafe fn global_data_modify_( key: uint, op: &fn(Option<~T>) -> Option<~T>) { @@ -123,6 +124,45 @@ unsafe fn global_data_modify_( } } } +#[cfg(not(stage0))] +unsafe fn global_data_modify_( + key: uint, op: &fn(Option<~T>) -> Option<~T>) { + + let mut old_dtor = None; + do get_global_state().with |gs| { + let (maybe_new_value, maybe_dtor) = match gs.map.pop(&key) { + Some((ptr, dtor)) => { + let value: ~T = transmute(ptr); + (op(Some(value)), Some(dtor)) + } + None => { + (op(None), None) + } + }; + match maybe_new_value { + Some(value) => { + let data: *c_void = transmute(value); + let dtor: ~fn() = match maybe_dtor { + Some(dtor) => dtor, + None => { + let dtor: ~fn() = || { + let _destroy_value: ~T = transmute(data); + }; + dtor + } + }; + let value = (data, dtor); + gs.map.insert(key, value); + } + None => { + match maybe_dtor { + Some(dtor) => old_dtor = Some(dtor), + None => () + } + } + } + } +} pub unsafe fn global_data_clone( key: GlobalDataKey) -> Option { diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs index e75cf2c01c675..55cdeeb7826c0 100644 --- a/src/libstd/unstable/lang.rs +++ b/src/libstd/unstable/lang.rs @@ -384,6 +384,7 @@ pub unsafe fn strdup_uniq(ptr: *c_uchar, len: uint) -> ~str { } #[lang="start"] +#[cfg(stage0)] pub fn start(main: *u8, argc: int, argv: **c_char, crate_map: *u8) -> int { use rt; @@ -419,3 +420,38 @@ pub fn start(main: *u8, argc: int, argv: **c_char, crate_map: *c_void) -> c_int; } } +#[lang="start"] +#[cfg(not(stage0))] +pub fn start(main: *u8, argc: int, argv: **c_char, + crate_map: *u8) -> int { + use rt; + use sys::Closure; + use ptr; + use cast; + use os; + + unsafe { + let use_old_rt = os::getenv("RUST_NEWRT").is_none(); + if use_old_rt { + return rust_start(main as *c_void, argc as c_int, argv, + crate_map as *c_void) as int; + } else { + return do rt::start(argc, argv as **u8, crate_map) { + // `main` is an `fn() -> ()` that doesn't take an environment + // XXX: Could also call this as an `extern "Rust" fn` once they work + let main = Closure { + code: main as *(), + env: ptr::null(), + }; + let mainfn: &fn() = cast::transmute(main); + + mainfn(); + }; + } + } + + extern { + fn rust_start(main: *c_void, argc: c_int, argv: **c_char, + crate_map: *c_void) -> c_int; + } +}