diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-06-04 00:01:40 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-06-06 23:00:01 -0700 |
| commit | 75014f7b1790e7ebdf13d38acc04dfdab6e450e9 (patch) | |
| tree | 46fb046e002a37ba60f6e8b8ef5ee0675fbb7fd8 | |
| parent | d743b8831e6dc5b390af112cc23159d667cf583b (diff) | |
| download | rust-75014f7b1790e7ebdf13d38acc04dfdab6e450e9.tar.gz rust-75014f7b1790e7ebdf13d38acc04dfdab6e450e9.zip | |
libs: Fix miscellaneous fallout of librustrt
34 files changed, 263 insertions, 288 deletions
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 511983da4f7..ca7ed6f4ba0 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -96,6 +96,21 @@ pub mod owned; pub mod arc; pub mod rc; +// FIXME(#14344): When linking liballoc with libstd, this library will be linked +// as an rlib (it only exists as an rlib). It turns out that an +// optimized standard library doesn't actually use *any* symbols +// from this library. Everything is inlined and optimized away. +// This means that linkers will actually omit the object for this +// file, even though it may be needed in the future. +// +// To get around this for now, we define a dummy symbol which +// will never get inlined so the stdlib can call it. The stdlib's +// reference to this symbol will cause this library's object file +// to get linked in to libstd successfully (the linker won't +// optimize it out). +#[doc(hidden)] +pub fn fixme_14344_be_sure_to_link_to_collections() {} + #[cfg(not(test))] #[doc(hidden)] mod std { diff --git a/src/liballoc/util.rs b/src/liballoc/util.rs index 64d62035890..7e35af79eab 100644 --- a/src/liballoc/util.rs +++ b/src/liballoc/util.rs @@ -28,20 +28,3 @@ fn align_to(size: uint, align: uint) -> uint { assert!(align != 0); (size + align - 1) & !(align - 1) } - -// FIXME(#14344): When linking liballoc with libstd, this library will be linked -// as an rlib (it only exists as an rlib). It turns out that an -// optimized standard library doesn't actually use *any* symbols -// from this library. Everything is inlined and optimized away. -// This means that linkers will actually omit the object for this -// file, even though it may be needed in the future. -// -// To get around this for now, we define a dummy symbol which -// will never get inlined so the stdlib can call it. The stdlib's -// reference to this symbol will cause this library's object file -// to get linked in to libstd successfully (the linker won't -// optimize it out). -#[deprecated] -#[doc(hidden)] -pub fn make_stdlib_link_work() {} - diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index a65c06107ce..c46ea84a765 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -72,6 +72,10 @@ fn expect<T>(a: core::option::Option<T>, b: &str) -> T { } } +// FIXME(#14344) this shouldn't be necessary +#[doc(hidden)] +pub fn fixme_14344_be_sure_to_link_to_collections() {} + #[cfg(not(test))] mod std { pub use core::fmt; // necessary for fail!() diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index e631b8b77cf..4798218e3ff 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -862,7 +862,7 @@ mod tests { use std::prelude::*; use std::rand::{Rng, task_rng}; use std::rc::Rc; - use std::unstable; + use std::rt; use slice::*; use vec::Vec; @@ -1104,9 +1104,9 @@ mod tests { #[test] fn test_swap_remove_noncopyable() { // Tests that we don't accidentally run destructors twice. - let mut v = vec![unstable::sync::Exclusive::new(()), - unstable::sync::Exclusive::new(()), - unstable::sync::Exclusive::new(())]; + let mut v = vec![rt::exclusive::Exclusive::new(()), + rt::exclusive::Exclusive::new(()), + rt::exclusive::Exclusive::new(())]; let mut _e = v.swap_remove(0); assert_eq!(v.len(), 2); _e = v.swap_remove(1); diff --git a/src/libgreen/basic.rs b/src/libgreen/basic.rs index 1ebebbe555e..7f033a1bc61 100644 --- a/src/libgreen/basic.rs +++ b/src/libgreen/basic.rs @@ -20,7 +20,7 @@ use std::sync::atomics; use std::mem; use std::rt::rtio::{EventLoop, IoFactory, RemoteCallback}; use std::rt::rtio::{PausableIdleCallback, Callback}; -use std::unstable::sync::Exclusive; +use std::rt::exclusive::Exclusive; /// This is the only exported function from this module. pub fn event_loop() -> Box<EventLoop:Send> { @@ -31,7 +31,7 @@ struct BasicLoop { work: Vec<proc():Send>, // pending work remotes: Vec<(uint, Box<Callback:Send>)>, next_remote: uint, - messages: Exclusive<Vec<Message>>, + messages: Arc<Exclusive<Vec<Message>>>, idle: Option<Box<Callback:Send>>, idle_active: Option<Arc<atomics::AtomicBool>>, } @@ -46,7 +46,7 @@ impl BasicLoop { idle_active: None, next_remote: 0, remotes: vec![], - messages: Exclusive::new(vec![]), + messages: Arc::new(Exclusive::new(Vec::new())), } } @@ -61,19 +61,10 @@ impl BasicLoop { fn remote_work(&mut self) { let messages = unsafe { - self.messages.with(|messages| { - if messages.len() > 0 { - Some(mem::replace(messages, vec![])) - } else { - None - } - }) - }; - let messages = match messages { - Some(m) => m, None => return + mem::replace(&mut *self.messages.lock(), Vec::new()) }; - for message in messages.iter() { - self.message(*message); + for message in messages.move_iter() { + self.message(message); } } @@ -125,13 +116,13 @@ impl EventLoop for BasicLoop { } unsafe { + let mut messages = self.messages.lock(); // We block here if we have no messages to process and we may // receive a message at a later date - self.messages.hold_and_wait(|messages| { - self.remotes.len() > 0 && - messages.len() == 0 && - self.work.len() == 0 - }) + if self.remotes.len() > 0 && messages.len() == 0 && + self.work.len() == 0 { + messages.wait() + } } } } @@ -165,33 +156,29 @@ impl EventLoop for BasicLoop { } struct BasicRemote { - queue: Exclusive<Vec<Message>>, + queue: Arc<Exclusive<Vec<Message>>>, id: uint, } impl BasicRemote { - fn new(queue: Exclusive<Vec<Message>>, id: uint) -> BasicRemote { + fn new(queue: Arc<Exclusive<Vec<Message>>>, id: uint) -> BasicRemote { BasicRemote { queue: queue, id: id } } } impl RemoteCallback for BasicRemote { fn fire(&mut self) { - unsafe { - self.queue.hold_and_signal(|queue| { - queue.push(RunRemote(self.id)); - }) - } + let mut queue = unsafe { self.queue.lock() }; + queue.push(RunRemote(self.id)); + queue.signal(); } } impl Drop for BasicRemote { fn drop(&mut self) { - unsafe { - self.queue.hold_and_signal(|queue| { - queue.push(RemoveRemote(self.id)); - }) - } + let mut queue = unsafe { self.queue.lock() }; + queue.push(RemoveRemote(self.id)); + queue.signal(); } } @@ -216,7 +203,7 @@ impl Drop for BasicPausable { #[cfg(test)] mod test { - use std::task::TaskOpts; + use std::rt::task::TaskOpts; use basic; use PoolConfig; diff --git a/src/libgreen/lib.rs b/src/libgreen/lib.rs index c75d69480ce..333ac80907f 100644 --- a/src/libgreen/lib.rs +++ b/src/libgreen/lib.rs @@ -160,7 +160,7 @@ //! # Using a scheduler pool //! //! ```rust -//! use std::task::TaskOpts; +//! use std::rt::task::TaskOpts; //! use green::{SchedPool, PoolConfig}; //! use green::sched::{PinnedTask, TaskFromFriend}; //! @@ -221,10 +221,10 @@ use std::mem::replace; use std::os; use std::rt::rtio; use std::rt::thread::Thread; +use std::rt::task::TaskOpts; use std::rt; use std::sync::atomics::{SeqCst, AtomicUint, INIT_ATOMIC_UINT}; use std::sync::deque; -use std::task::TaskOpts; use sched::{Shutdown, Scheduler, SchedHandle, TaskFromFriend, NewNeighbor}; use sleeper_list::SleeperList; @@ -319,7 +319,7 @@ pub fn run(event_loop_factory: fn() -> Box<rtio::EventLoop:Send>, let mut pool = SchedPool::new(cfg); let (tx, rx) = channel(); let mut opts = TaskOpts::new(); - opts.notify_chan = Some(tx); + opts.on_exit = Some(proc(r) tx.send(r)); opts.name = Some("<main>".into_maybe_owned()); pool.spawn(opts, main); diff --git a/src/libgreen/sched.rs b/src/libgreen/sched.rs index e410d2719b1..f55dc92eac6 100644 --- a/src/libgreen/sched.rs +++ b/src/libgreen/sched.rs @@ -10,11 +10,11 @@ use std::mem; use std::rt::local::Local; +use std::rt::mutex::NativeMutex; use std::rt::rtio::{RemoteCallback, PausableIdleCallback, Callback, EventLoop}; use std::rt::task::BlockedTask; use std::rt::task::Task; use std::sync::deque; -use std::unstable::mutex::NativeMutex; use std::raw; use std::rand::{XorShiftRng, Rng, Rand}; @@ -1022,7 +1022,7 @@ fn new_sched_rng() -> XorShiftRng { mod test { use rustuv; - use std::task::TaskOpts; + use std::rt::task::TaskOpts; use std::rt::task::Task; use std::rt::local::Local; @@ -1475,7 +1475,7 @@ mod test { #[test] fn test_spawn_sched_blocking() { - use std::unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT}; + use std::rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT}; static mut LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT; // Testing that a task in one scheduler can block in foreign code diff --git a/src/libgreen/simple.rs b/src/libgreen/simple.rs index 49aef15f93b..7b738ed9c7c 100644 --- a/src/libgreen/simple.rs +++ b/src/libgreen/simple.rs @@ -15,10 +15,9 @@ use std::any::Any; use std::mem; use std::rt::Runtime; use std::rt::local::Local; +use std::rt::mutex::NativeMutex; use std::rt::rtio; -use std::rt::task::{Task, BlockedTask}; -use std::task::TaskOpts; -use std::unstable::mutex::NativeMutex; +use std::rt::task::{Task, BlockedTask, TaskOpts}; struct SimpleTask { lock: NativeMutex, diff --git a/src/libgreen/stack.rs b/src/libgreen/stack.rs index f42d636cafb..2e385f75e1d 100644 --- a/src/libgreen/stack.rs +++ b/src/libgreen/stack.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::rt::env::max_cached_stacks; +use std::sync::atomics; use std::os::{errno, page_size, MemoryMap, MapReadable, MapWritable, - MapNonStandardFlags, MapVirtual}; + MapNonStandardFlags, MapVirtual, getenv}; use libc; /// A task's stack. The name "Stack" is a vestige of segmented stacks. @@ -151,6 +151,22 @@ impl StackPool { } } +fn max_cached_stacks() -> uint { + static mut AMT: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT; + match unsafe { AMT.load(atomics::SeqCst) } { + 0 => {} + n => return n - 1, + } + let amt = getenv("RUST_MAX_CACHED_STACKS").and_then(|s| from_str(s.as_slice())); + // This default corresponds to 20M of cache per scheduler (at the + // default size). + let amt = amt.unwrap_or(10); + // 0 is our sentinel value, so ensure that we'll never see 0 after + // initialization has run + unsafe { AMT.store(amt + 1, atomics::SeqCst); } + return amt; +} + extern { fn rust_valgrind_stack_register(start: *libc::uintptr_t, end: *libc::uintptr_t) -> libc::c_uint; diff --git a/src/libgreen/task.rs b/src/libgreen/task.rs index f50f65af6f9..91ebad3b3f8 100644 --- a/src/libgreen/task.rs +++ b/src/libgreen/task.rs @@ -22,13 +22,12 @@ use std::any::Any; use std::mem; use std::raw; use std::rt::Runtime; -use std::rt::env; use std::rt::local::Local; +use std::rt::mutex::NativeMutex; use std::rt::rtio; use std::rt::stack; -use std::rt::task::{Task, BlockedTask, SendMessage}; -use std::task::TaskOpts; -use std::unstable::mutex::NativeMutex; +use std::rt::task::{Task, BlockedTask, TaskOpts}; +use std::rt; use context::Context; use coroutine::Coroutine; @@ -142,7 +141,7 @@ impl GreenTask { let mut ops = GreenTask::new_typed(None, TypeGreen(Some(home))); // Allocate a stack for us to run on - let stack_size = stack_size.unwrap_or_else(|| env::min_stack()); + let stack_size = stack_size.unwrap_or_else(|| rt::min_stack()); let mut stack = stack_pool.take_stack(stack_size); let context = Context::new(bootstrap_green_task, ops.as_uint(), start, &mut stack); @@ -176,23 +175,13 @@ impl GreenTask { pub fn configure(pool: &mut StackPool, opts: TaskOpts, f: proc():Send) -> Box<GreenTask> { - let TaskOpts { - notify_chan, name, stack_size, - stderr, stdout, - } = opts; + let TaskOpts { name, stack_size, on_exit } = opts; let mut green = GreenTask::new(pool, stack_size, f); { let task = green.task.get_mut_ref(); task.name = name; - task.stderr = stderr; - task.stdout = stdout; - match notify_chan { - Some(chan) => { - task.death.on_exit = Some(SendMessage(chan)); - } - None => {} - } + task.death.on_exit = on_exit; } return green; } @@ -490,7 +479,7 @@ mod tests { use std::rt::local::Local; use std::rt::task::Task; use std::task; - use std::task::TaskOpts; + use std::rt::task::TaskOpts; use super::super::{PoolConfig, SchedPool}; use super::GreenTask; @@ -529,7 +518,7 @@ mod tests { opts.name = Some("test".into_maybe_owned()); opts.stack_size = Some(20 * 4096); let (tx, rx) = channel(); - opts.notify_chan = Some(tx); + opts.on_exit = Some(proc(r) tx.send(r)); spawn_opts(opts, proc() {}); assert!(rx.recv().is_ok()); } @@ -538,7 +527,7 @@ mod tests { fn smoke_opts_fail() { let mut opts = TaskOpts::new(); let (tx, rx) = channel(); - opts.notify_chan = Some(tx); + opts.on_exit = Some(proc(r) tx.send(r)); spawn_opts(opts, proc() { fail!() }); assert!(rx.recv().is_err()); } diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 5b7f58fcb81..b833b2a6515 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -172,6 +172,7 @@ pub use funcs::bsd43::{shutdown}; #[cfg(unix)] pub use consts::os::posix88::{ENOTCONN, ECONNABORTED, EADDRNOTAVAIL, EINTR}; #[cfg(unix)] pub use consts::os::posix88::{EADDRINUSE, ENOENT, EISDIR, EAGAIN, EWOULDBLOCK}; #[cfg(unix)] pub use consts::os::posix88::{ECANCELED, SIGINT, EINPROGRESS}; +#[cfg(unix)] pub use consts::os::posix88::{ENOSYS, ENOTTY, ETIMEDOUT}; #[cfg(unix)] pub use consts::os::posix88::{SIGTERM, SIGKILL, SIGPIPE, PROT_NONE}; #[cfg(unix)] pub use consts::os::posix01::{SIG_IGN}; #[cfg(unix)] pub use consts::os::bsd44::{AF_UNIX}; @@ -195,7 +196,7 @@ pub use funcs::bsd43::{shutdown}; #[cfg(windows)] pub use consts::os::c95::{WSAECONNREFUSED, WSAECONNRESET, WSAEACCES}; #[cfg(windows)] pub use consts::os::c95::{WSAEWOULDBLOCK, WSAENOTCONN, WSAECONNABORTED}; #[cfg(windows)] pub use consts::os::c95::{WSAEADDRNOTAVAIL, WSAEADDRINUSE, WSAEINTR}; -#[cfg(windows)] pub use consts::os::c95::{WSAEINPROGRESS}; +#[cfg(windows)] pub use consts::os::c95::{WSAEINPROGRESS, WSAEINVAL}; #[cfg(windows)] pub use consts::os::extra::{ERROR_INSUFFICIENT_BUFFER}; #[cfg(windows)] pub use consts::os::extra::{O_BINARY, O_NOINHERIT, PAGE_NOACCESS}; #[cfg(windows)] pub use consts::os::extra::{PAGE_READONLY, PAGE_READWRITE, PAGE_EXECUTE}; @@ -205,6 +206,9 @@ pub use funcs::bsd43::{shutdown}; #[cfg(windows)] pub use consts::os::extra::{ERROR_ALREADY_EXISTS, ERROR_NO_DATA}; #[cfg(windows)] pub use consts::os::extra::{ERROR_FILE_NOT_FOUND, ERROR_INVALID_NAME}; #[cfg(windows)] pub use consts::os::extra::{ERROR_BROKEN_PIPE, ERROR_INVALID_FUNCTION}; +#[cfg(windows)] pub use consts::os::extra::{ERROR_CALL_NOT_IMPLEMENTED}; +#[cfg(windows)] pub use consts::os::extra::{ERROR_NOTHING_TO_TERMINATE}; +#[cfg(windows)] pub use consts::os::extra::{ERROR_INVALID_HANDLE}; #[cfg(windows)] pub use consts::os::extra::{TRUE, FALSE, INFINITE}; #[cfg(windows)] pub use consts::os::extra::{PROCESS_TERMINATE, PROCESS_QUERY_INFORMATION}; #[cfg(windows)] pub use consts::os::extra::{STILL_ACTIVE, DETACHED_PROCESS}; @@ -1758,6 +1762,7 @@ pub mod consts { pub static ERROR_NO_DATA: c_int = 232; pub static ERROR_INVALID_ADDRESS : c_int = 487; pub static ERROR_PIPE_CONNECTED: c_int = 535; + pub static ERROR_NOTHING_TO_TERMINATE: c_int = 758; pub static ERROR_OPERATION_ABORTED: c_int = 995; pub static ERROR_IO_PENDING: c_int = 997; pub static ERROR_FILE_INVALID : c_int = 1006; diff --git a/src/libnative/io/addrinfo.rs b/src/libnative/io/addrinfo.rs index b79061dd9d6..255c3f4bd21 100644 --- a/src/libnative/io/addrinfo.rs +++ b/src/libnative/io/addrinfo.rs @@ -92,8 +92,6 @@ extern "system" { fn freeaddrinfo(res: *mut libc::addrinfo); #[cfg(not(windows))] fn gai_strerror(errcode: c_int) -> *c_char; - #[cfg(windows)] - fn WSAGetLastError() -> c_int; } #[cfg(windows)] diff --git a/src/libnative/io/file_win32.rs b/src/libnative/io/file_win32.rs index 2cf54ab4007..2a5b78e5506 100644 --- a/src/libnative/io/file_win32.rs +++ b/src/libnative/io/file_win32.rs @@ -14,17 +14,14 @@ use alloc::arc::Arc; use libc::{c_int, c_void}; use libc; use std::c_str::CString; -use std::io::IoError; -use std::io; use std::mem; use std::os::win32::{as_utf16_p, fill_utf16_buf_and_decode}; use std::ptr; use std::rt::rtio; +use std::rt::rtio::IoResult; use std::str; use std::vec; -use io::IoResult; - pub type fd_t = libc::c_int; struct Inner { @@ -52,7 +49,7 @@ impl FileDesc { }) } } - pub fn inner_read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> { + pub fn inner_read(&mut self, buf: &mut [u8]) -> IoResult<uint> { let mut read = 0; let ret = unsafe { libc::ReadFile(self.handle(), buf.as_ptr() as libc::LPVOID, @@ -65,7 +62,7 @@ impl FileDesc { Err(super::last_error()) } } - pub fn inner_write(&mut self, buf: &[u8]) -> Result<(), IoError> { + pub fn inner_write(&mut self, buf: &[u8]) -> IoResult<()> { let mut cur = buf.as_ptr(); let mut remaining = buf.len(); while remaining > 0 { @@ -93,11 +90,11 @@ impl FileDesc { // A version of seek that takes &self so that tell can call it // - the private seek should of course take &mut self. - fn seek_common(&self, pos: i64, style: io::SeekStyle) -> Result<u64, IoError> { + fn seek_common(&self, pos: i64, style: rtio::SeekStyle) -> IoResult<u64> { let whence = match style { - io::SeekSet => libc::FILE_BEGIN, - io::SeekEnd => libc::FILE_END, - io::SeekCur => libc::FILE_CURRENT, + rtio::SeekSet => libc::FILE_BEGIN, + rtio::SeekEnd => libc::FILE_END, + rtio::SeekCur => libc::FILE_CURRENT, }; unsafe { let mut newpos = 0; @@ -111,27 +108,15 @@ impl FileDesc { } -impl io::Reader for FileDesc { - fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> { - self.inner_read(buf) - } -} - -impl io::Writer for FileDesc { - fn write(&mut self, buf: &[u8]) -> io::IoResult<()> { - self.inner_write(buf) - } -} - impl rtio::RtioFileStream for FileDesc { - fn read(&mut self, buf: &mut [u8]) -> Result<int, IoError> { + fn read(&mut self, buf: &mut [u8]) -> IoResult<int> { self.inner_read(buf).map(|i| i as int) } - fn write(&mut self, buf: &[u8]) -> Result<(), IoError> { + fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.inner_write(buf) } - fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError> { + fn pread(&mut self, buf: &mut [u8], offset: u64) -> IoResult<int> { let mut read = 0; let mut overlap: libc::OVERLAPPED = unsafe { mem::zeroed() }; overlap.Offset = offset as libc::DWORD; @@ -147,7 +132,7 @@ impl rtio::RtioFileStream for FileDesc { Err(super::last_error()) } } - fn pwrite(&mut self, buf: &[u8], mut offset: u64) -> Result<(), IoError> { + fn pwrite(&mut self, buf: &[u8], mut offset: u64) -> IoResult<()> { let mut cur = buf.as_ptr(); let mut remaining = buf.len(); let mut overlap: libc::OVERLAPPED = unsafe { mem::zeroed() }; @@ -171,36 +156,36 @@ impl rtio::RtioFileStream for FileDesc { Ok(()) } - fn seek(&mut self, pos: i64, style: io::SeekStyle) -> Result<u64, IoError> { + fn seek(&mut self, pos: i64, style: rtio::SeekStyle) -> IoResult<u64> { self.seek_common(pos, style) } - fn tell(&self) -> Result<u64, IoError> { - self.seek_common(0, io::SeekCur) + fn tell(&self) -> IoResult<u64> { + self.seek_common(0, rtio::SeekCur) } - fn fsync(&mut self) -> Result<(), IoError> { + fn fsync(&mut self) -> IoResult<()> { super::mkerr_winbool(unsafe { libc::FlushFileBuffers(self.handle()) }) } - fn datasync(&mut self) -> Result<(), IoError> { return self.fsync(); } + fn datasync(&mut self) -> IoResult<()> { return self.fsync(); } - fn truncate(&mut self, offset: i64) -> Result<(), IoError> { + fn truncate(&mut self, offset: i64) -> IoResult<()> { let orig_pos = try!(self.tell()); - let _ = try!(self.seek(offset, io::SeekSet)); + let _ = try!(self.seek(offset, rtio::SeekSet)); let ret = unsafe { match libc::SetEndOfFile(self.handle()) { 0 => Err(super::last_error()), _ => Ok(()) } }; - let _ = self.seek(orig_pos as i64, io::SeekSet); + let _ = self.seek(orig_pos as i64, rtio::SeekSet); return ret; } - fn fstat(&mut self) -> IoResult<io::FileStat> { + fn fstat(&mut self) -> IoResult<rtio::FileStat> { let mut stat: libc::stat = unsafe { mem::zeroed() }; match unsafe { libc::fstat(self.fd(), &mut stat) } { 0 => Ok(mkstat(&stat)), @@ -210,10 +195,10 @@ impl rtio::RtioFileStream for FileDesc { } impl rtio::RtioPipe for FileDesc { - fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> { + fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.inner_read(buf) } - fn write(&mut self, buf: &[u8]) -> Result<(), IoError> { + fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.inner_write(buf) } fn clone(&self) -> Box<rtio::RtioPipe:Send> { @@ -225,10 +210,10 @@ impl rtio::RtioPipe for FileDesc { // std::io::PipeStream. If the functionality is exposed in the future, then // these methods will need to be implemented. fn close_read(&mut self) -> IoResult<()> { - Err(io::standard_error(io::InvalidInput)) + Err(super::unimpl()) } fn close_write(&mut self) -> IoResult<()> { - Err(io::standard_error(io::InvalidInput)) + Err(super::unimpl()) } fn set_timeout(&mut self, _t: Option<u64>) {} fn set_read_timeout(&mut self, _t: Option<u64>) {} @@ -236,16 +221,16 @@ impl rtio::RtioPipe for FileDesc { } impl rtio::RtioTTY for FileDesc { - fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> { + fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.inner_read(buf) } - fn write(&mut self, buf: &[u8]) -> Result<(), IoError> { + fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.inner_write(buf) } - fn set_raw(&mut self, _raw: bool) -> Result<(), IoError> { + fn set_raw(&mut self, _raw: bool) -> IoResult<()> { Err(super::unimpl()) } - fn get_winsize(&mut self) -> Result<(int, int), IoError> { + fn get_winsize(&mut self) -> IoResult<(int, int)> { Err(super::unimpl()) } fn isatty(&self) -> bool { false } @@ -268,24 +253,24 @@ impl Drop for Inner { } } -pub fn open(path: &CString, fm: io::FileMode, fa: io::FileAccess) +pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess) -> IoResult<FileDesc> { // Flags passed to open_osfhandle let flags = match fm { - io::Open => 0, - io::Append => libc::O_APPEND, - io::Truncate => libc::O_TRUNC, + rtio::Open => 0, + rtio::Append => libc::O_APPEND, + rtio::Truncate => libc::O_TRUNC, }; let flags = match fa { - io::Read => flags | libc::O_RDONLY, - io::Write => flags | libc::O_WRONLY | libc::O_CREAT, - io::ReadWrite => flags | libc::O_RDWR | libc::O_CREAT, + rtio::Read => flags | libc::O_RDONLY, + rtio::Write => flags | libc::O_WRONLY | libc::O_CREAT, + rtio::ReadWrite => flags | libc::O_RDWR | libc::O_CREAT, }; let mut dwDesiredAccess = match fa { - io::Read => libc::FILE_GENERIC_READ, - io::Write => libc::FILE_GENERIC_WRITE, - io::ReadWrite => libc::FILE_GENERIC_READ | libc::FILE_GENERIC_WRITE + rtio::Read => libc::FILE_GENERIC_READ, + rtio::Write => libc::FILE_GENERIC_WRITE, + rtio::ReadWrite => libc::FILE_GENERIC_READ | libc::FILE_GENERIC_WRITE }; // libuv has a good comment about this, but the basic idea is what we try to @@ -295,15 +280,15 @@ pub fn open(path: &CString, fm: io::FileMode, fa: io::FileAccess) libc::FILE_SHARE_DELETE; let dwCreationDisposition = match (fm, fa) { - (io::Truncate, io::Read) => libc::TRUNCATE_EXISTING, - (io::Truncate, _) => libc::CREATE_ALWAYS, - (io::Open, io::Read) => libc::OPEN_EXISTING, - (io::Open, _) => libc::OPEN_ALWAYS, - (io::Append, io::Read) => { + (rtio::Truncate, rtio::Read) => libc::TRUNCATE_EXISTING, + (rtio::Truncate, _) => libc::CREATE_ALWAYS, + (rtio::Open, rtio::Read) => libc::OPEN_EXISTING, + (rtio::Open, _) => libc::OPEN_ALWAYS, + (rtio::Append, rtio::Read) => { dwDesiredAccess |= libc::FILE_APPEND_DATA; libc::OPEN_EXISTING } - (io::Append, _) => { + (rtio::Append, _) => { dwDesiredAccess &= !libc::FILE_WRITE_DATA; dwDesiredAccess |= libc::FILE_APPEND_DATA; libc::OPEN_ALWAYS @@ -338,7 +323,7 @@ pub fn open(path: &CString, fm: io::FileMode, fa: io::FileAccess) } } -pub fn mkdir(p: &CString, _mode: io::FilePermission) -> IoResult<()> { +pub fn mkdir(p: &CString, _mode: uint) -> IoResult<()> { super::mkerr_winbool(unsafe { // FIXME: turn mode into something useful? #2623 as_utf16_p(p.as_str().unwrap(), |buf| { @@ -413,9 +398,9 @@ pub fn rename(old: &CString, new: &CString) -> IoResult<()> { }) } -pub fn chmod(p: &CString, mode: io::FilePermission) -> IoResult<()> { +pub fn chmod(p: &CString, mode: uint) -> IoResult<()> { super::mkerr_libc(as_utf16_p(p.as_str().unwrap(), |p| unsafe { - libc::wchmod(p, mode.bits() as libc::c_int) + libc::wchmod(p, mode as libc::c_int) })) } @@ -430,7 +415,7 @@ pub fn chown(_p: &CString, _uid: int, _gid: int) -> IoResult<()> { Ok(()) } -pub fn readlink(p: &CString) -> IoResult<Path> { +pub fn readlink(p: &CString) -> IoResult<CString> { // FIXME: I have a feeling that this reads intermediate symlinks as well. use io::c::compat::kernel32::GetFinalPathNameByHandleW; let handle = unsafe { @@ -457,9 +442,9 @@ pub fn readlink(p: &CString) -> IoResult<Path> { }); let ret = match ret { Some(ref s) if s.as_slice().starts_with(r"\\?\") => { - Ok(Path::new(s.as_slice().slice_from(4))) + Ok(Path::new(s.as_slice().slice_from(4)).to_c_str()) } - Some(s) => Ok(Path::new(s)), + Some(s) => Ok(Path::new(s).to_c_str()), None => Err(super::last_error()), }; assert!(unsafe { libc::CloseHandle(handle) } != 0); @@ -483,39 +468,28 @@ pub fn link(src: &CString, dst: &CString) -> IoResult<()> { })) } -fn mkstat(stat: &libc::stat) -> io::FileStat { - let kind = match (stat.st_mode as c_int) & libc::S_IFMT { - libc::S_IFREG => io::TypeFile, - libc::S_IFDIR => io::TypeDirectory, - libc::S_IFIFO => io::TypeNamedPipe, - libc::S_IFBLK => io::TypeBlockSpecial, - libc::S_IFLNK => io::TypeSymlink, - _ => io::TypeUnknown, - }; - - io::FileStat { +fn mkstat(stat: &libc::stat) -> rtio::FileStat { + rtio::FileStat { size: stat.st_size as u64, - kind: kind, - perm: io::FilePermission::from_bits_truncate(stat.st_mode as u32), + kind: stat.st_mode as u64, + perm: stat.st_mode as u64, created: stat.st_ctime as u64, modified: stat.st_mtime as u64, accessed: stat.st_atime as u64, - unstable: io::UnstableFileStat { - device: stat.st_dev as u64, - inode: stat.st_ino as u64, - rdev: stat.st_rdev as u64, - nlink: stat.st_nlink as u64, - uid: stat.st_uid as u64, - gid: stat.st_gid as u64, - blksize: 0, - blocks: 0, - flags: 0, - gen: 0, - } + device: stat.st_dev as u64, + inode: stat.st_ino as u64, + rdev: stat.st_rdev as u64, + nlink: stat.st_nlink as u64, + uid: stat.st_uid as u64, + gid: stat.st_gid as u64, + blksize: 0, + blocks: 0, + flags: 0, + gen: 0, } } -pub fn stat(p: &CString) -> IoResult<io::FileStat> { +pub fn stat(p: &CString) -> IoResult<rtio::FileStat> { let mut stat: libc::stat = unsafe { mem::zeroed() }; as_utf16_p(p.as_str().unwrap(), |up| { match unsafe { libc::wstat(up, &mut stat) } { @@ -525,7 +499,7 @@ pub fn stat(p: &CString) -> IoResult<io::FileStat> { }) } -pub fn lstat(_p: &CString) -> IoResult<io::FileStat> { +pub fn lstat(_p: &CString) -> IoResult<rtio::FileStat> { // FIXME: implementation is missing Err(super::unimpl()) } diff --git a/src/libnative/io/net.rs b/src/libnative/io/net.rs index 68cc5273b5e..24956e514ec 100644 --- a/src/libnative/io/net.rs +++ b/src/libnative/io/net.rs @@ -135,10 +135,12 @@ pub fn getsockopt<T: Copy>(fd: sock_t, opt: libc::c_int, } #[cfg(windows)] -fn last_error() -> IoError { +pub fn last_error() -> IoError { + use std::os; let code = unsafe { c::WSAGetLastError() as uint }; IoError { code: code, + extra: 0, detail: Some(os::error_string(code)), } } @@ -225,7 +227,7 @@ pub fn init() {} pub fn init() { unsafe { - use std::unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT}; + use std::rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT}; static mut INITIALIZED: bool = false; static mut LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT; diff --git a/src/libnative/io/pipe_win32.rs b/src/libnative/io/pipe_win32.rs index cd4cbf2c90f..a5694436b97 100644 --- a/src/libnative/io/pipe_win32.rs +++ b/src/libnative/io/pipe_win32.rs @@ -87,16 +87,15 @@ use alloc::arc::Arc; use libc; use std::c_str::CString; -use std::io; use std::mem; use std::os::win32::as_utf16_p; use std::os; use std::ptr; use std::rt::rtio; +use std::rt::rtio::{IoResult, IoError}; use std::sync::atomics; -use std::unstable::mutex; +use std::rt::mutex; -use super::IoResult; use super::c; use super::util; @@ -190,6 +189,14 @@ pub fn await(handle: libc::HANDLE, deadline: u64, } } +fn epipe() -> IoError { + IoError { + code: libc::ERROR_BROKEN_PIPE as uint, + extra: 0, + detail: None, + } +} + //////////////////////////////////////////////////////////////////////////////// // Unix Streams //////////////////////////////////////////////////////////////////////////////// @@ -355,7 +362,7 @@ impl rtio::RtioPipe for UnixStream { // See comments in close_read() about why this lock is necessary. let guard = unsafe { self.inner.lock.lock() }; if self.read_closed() { - return Err(io::standard_error(io::EndOfFile)) + return Err(util::eof()) } // Issue a nonblocking requests, succeeding quickly if it happened to @@ -403,10 +410,10 @@ impl rtio::RtioPipe for UnixStream { // If the reading half is now closed, then we're done. If we woke up // because the writing half was closed, keep trying. if !succeeded { - return Err(io::standard_error(io::TimedOut)) + return Err(util::timeout("read timed out")) } if self.read_closed() { - return Err(io::standard_error(io::EndOfFile)) + return Err(util::eof()) } } } @@ -431,7 +438,7 @@ impl rtio::RtioPipe for UnixStream { // See comments in close_read() about why this lock is necessary. let guard = unsafe { self.inner.lock.lock() }; if self.write_closed() { - return Err(io::standard_error(io::BrokenPipe)) + return Err(epipe()) } let ret = unsafe { libc::WriteFile(self.handle(), @@ -445,7 +452,11 @@ impl rtio::RtioPipe for UnixStream { if ret == 0 { if err != libc::ERROR_IO_PENDING as uint { - return Err(io::IoError::from_errno(err, true)); + return Err(IoError { + code: err as uint, + extra: 0, + detail: Some(os::error_string(err as uint)), + }) } // Process a timeout if one is pending let succeeded = await(self.handle(), self.write_deadline, @@ -466,17 +477,17 @@ impl rtio::RtioPipe for UnixStream { if !succeeded { let amt = offset + bytes_written as uint; return if amt > 0 { - Err(io::IoError { - kind: io::ShortWrite(amt), - desc: "short write during write", - detail: None, + Err(IoError { + code: libc::ERROR_OPERATION_ABORTED as uint, + extra: amt, + detail: Some("short write during write".to_str()), }) } else { Err(util::timeout("write timed out")) } } if self.write_closed() { - return Err(io::standard_error(io::BrokenPipe)) + return Err(epipe()) } continue // retry } diff --git a/src/libnative/io/process.rs b/src/libnative/io/process.rs index 8b3f4debe5d..2c2b7cec1de 100644 --- a/src/libnative/io/process.rs +++ b/src/libnative/io/process.rs @@ -210,23 +210,23 @@ unsafe fn killpid(pid: pid_t, signal: int) -> IoResult<()> { if ret == 0 { Err(super::last_error()) } else if status != libc::STILL_ACTIVE { - Err(io::IoError { - kind: io::OtherIoError, - desc: "process no longer alive", + Err(IoError { + code: libc::ERROR_NOTHING_TO_TERMINATE as uint, + extra: 0, detail: None, }) } else { Ok(()) } } - io::process::PleaseExitSignal | io::process::MustDieSignal => { + 15 | 9 => { // sigterm or sigkill let ret = libc::TerminateProcess(handle, 1); super::mkerr_winbool(ret) } - _ => Err(io::IoError { - kind: io::OtherIoError, - desc: "unsupported signal on windows", - detail: None, + _ => Err(IoError { + code: libc::ERROR_CALL_NOT_IMPLEMENTED as uint, + extra: 0, + detail: Some("unsupported signal on windows".to_string()), }) }; let _ = libc::CloseHandle(handle); @@ -266,10 +266,10 @@ fn spawn_process_os(cfg: ProcessConfig, use std::mem; if cfg.gid.is_some() || cfg.uid.is_some() { - return Err(io::IoError { - kind: io::OtherIoError, - desc: "unsupported gid/uid requested on windows", - detail: None, + return Err(IoError { + code: libc::ERROR_CALL_NOT_IMPLEMENTED as uint, + extra: 0, + detail: Some("unsupported gid/uid requested on windows".to_str()), }) } diff --git a/src/libnative/io/timer_win32.rs b/src/libnative/io/timer_win32.rs index e7130de05c2..d175060dd98 100644 --- a/src/libnative/io/timer_win32.rs +++ b/src/libnative/io/timer_win32.rs @@ -23,10 +23,10 @@ use libc; use std::ptr; use std::rt::rtio; +use std::rt::rtio::{IoResult, Callback}; use std::comm; use io::helper_thread::Helper; -use io::IoResult; helper_init!(static mut HELPER: Helper<Req>) @@ -36,7 +36,7 @@ pub struct Timer { } pub enum Req { - NewTimer(libc::HANDLE, Sender<()>, bool), + NewTimer(libc::HANDLE, Box<Callback:Send>, bool), RemoveTimer(libc::HANDLE, Sender<()>), } @@ -79,8 +79,8 @@ fn helper(input: libc::HANDLE, messages: Receiver<Req>, _: ()) { } } else { let remove = { - match chans.get(idx as uint - 1) { - &(ref c, oneshot) => c.send_opt(()).is_err() || oneshot + match chans.get_mut(idx as uint - 1) { + &(ref mut c, oneshot) => { c.call(); oneshot } } }; if remove { @@ -148,9 +148,8 @@ impl rtio::RtioTimer for Timer { let _ = unsafe { imp::WaitForSingleObject(self.obj, libc::INFINITE) }; } - fn oneshot(&mut self, msecs: u64) -> Receiver<()> { + fn oneshot(&mut self, msecs: u64, cb: Box<Callback:Send>) { self.remove(); - let (tx, rx) = channel(); // see above for the calculation let due = -(msecs as i64 * 10000) as libc::LARGE_INTEGER; @@ -159,14 +158,12 @@ impl rtio::RtioTimer for Timer { ptr::mut_null(), 0) }, 1); - unsafe { HELPER.send(NewTimer(self.obj, tx, true)) } + unsafe { HELPER.send(NewTimer(self.obj, cb, true)) } self.on_worker = true; - return rx; } - fn period(&mut self, msecs: u64) -> Receiver<()> { + fn period(&mut self, msecs: u64, cb: Box<Callback:Send>) { self.remove(); - let (tx, rx) = channel(); // see above for the calculation let due = -(msecs as i64 * 10000) as libc::LARGE_INTEGER; @@ -175,10 +172,8 @@ impl rtio::RtioTimer for Timer { ptr::null(), ptr::mut_null(), 0) }, 1); - unsafe { HELPER.send(NewTimer(self.obj, tx, false)) } + unsafe { HELPER.send(NewTimer(self.obj, cb, false)) } self.on_worker = true; - - return rx; } } diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs index 1690c54285c..4234c085148 100644 --- a/src/librustrt/c_str.rs +++ b/src/librustrt/c_str.rs @@ -238,9 +238,15 @@ impl Container for CString { #[inline] fn len(&self) -> uint { if self.buf.is_null() { fail!("CString is null!"); } + let mut cur = self.buf; + let mut len = 0; unsafe { - ptr::position(self.buf, |c| *c == 0) + while *cur != 0 { + len += 1; + cur = cur.offset(1); + } } + return len; } } diff --git a/src/librustrt/lib.rs b/src/librustrt/lib.rs index 506df10aab2..3158687c6ab 100644 --- a/src/librustrt/lib.rs +++ b/src/librustrt/lib.rs @@ -113,6 +113,7 @@ pub fn init(argc: int, argv: **u8) { // FIXME(#14344) this shouldn't be necessary collections::fixme_14344_be_sure_to_link_to_collections(); alloc::fixme_14344_be_sure_to_link_to_collections(); + libc::issue_14344_workaround(); } /// Enqueues a procedure to run when the runtime is cleaned up diff --git a/src/librustrt/local_data.rs b/src/librustrt/local_data.rs index 88c154045c6..6b468bd0827 100644 --- a/src/librustrt/local_data.rs +++ b/src/librustrt/local_data.rs @@ -95,8 +95,6 @@ type TLSValue = Box<LocalData:Send>; // Gets the map from the runtime. Lazily initialises if not done so already. unsafe fn get_local_map() -> Option<&mut Map> { - use rt::local::Local; - if !Local::exists(None::<Task>) { return None } let task: *mut Task = Local::unsafe_borrow(); diff --git a/src/librustrt/task.rs b/src/librustrt/task.rs index f56b891ed9f..0640b2b9c77 100644 --- a/src/librustrt/task.rs +++ b/src/librustrt/task.rs @@ -18,10 +18,11 @@ use core::prelude::*; use alloc::arc::Arc; use alloc::owned::{AnyOwnExt, Box}; use core::any::Any; +use core::atomics::{AtomicUint, SeqCst}; +use core::finally::Finally; use core::iter::Take; use core::mem; -use core::finally::Finally; -use core::atomics::{AtomicUint, SeqCst}; +use core::raw; use local_data; use Runtime; @@ -142,18 +143,17 @@ impl Task { // TLS, or possibly some destructors for those objects being // annihilated invoke TLS. Sadly these two operations seemed to // be intertwined, and miraculously work for now... - let mut task = Local::borrow(None::<Task>); - let storage_map = { + drop({ + let mut task = Local::borrow(None::<Task>); let &LocalStorage(ref mut optmap) = &mut task.storage; optmap.take() - }; - drop(task); - drop(storage_map); + }); // Destroy remaining boxes. Also may run user dtors. - let mut task = Local::borrow(None::<Task>); - let mut heap = mem::replace(&mut task.heap, LocalHeap::new()); - drop(task); + let mut heap = { + let mut task = Local::borrow(None::<Task>); + mem::replace(&mut task.heap, LocalHeap::new()) + }; unsafe { heap.annihilate() } drop(heap); }) @@ -202,13 +202,16 @@ impl Task { // crops up. unsafe { let imp = self.imp.take_unwrap(); - let &(vtable, _): &(uint, uint) = mem::transmute(&imp); + let vtable = mem::transmute::<_, &raw::TraitObject>(&imp).vtable; match imp.wrap().move::<T>() { Ok(t) => Some(t), Err(t) => { - let (_, obj): (uint, uint) = mem::transmute(t); + let data = mem::transmute::<_, raw::TraitObject>(t).data; let obj: Box<Runtime:Send> = - mem::transmute((vtable, obj)); + mem::transmute(raw::TraitObject { + vtable: vtable, + data: data, + }); self.put_runtime(obj); None } diff --git a/src/librustrt/unwind.rs b/src/librustrt/unwind.rs index da6fd3644ce..2fd9f4ef1f1 100644 --- a/src/librustrt/unwind.rs +++ b/src/librustrt/unwind.rs @@ -121,7 +121,7 @@ impl Unwinder { self.cause = unsafe { try(f) }.err(); } - pub fn result(&mut self) -> TaskResult { + pub fn result(&mut self) -> Result { if self.unwinding { Err(self.cause.take().unwrap()) } else { @@ -150,10 +150,7 @@ impl Unwinder { /// guaranteed that a rust task is in place when invoking this function. /// Unwinding twice can lead to resource leaks where some destructors are not /// run. -pub unsafe fn try(f: ||) -> Result<(), Box<Any:Send>> { - use raw::Closure; - use libc::{c_void}; - +pub unsafe fn try(f: ||) -> ::core::result::Result<(), Box<Any:Send>> { let closure: Closure = mem::transmute(f); let ep = rust_try(try_fn, closure.code as *c_void, closure.env as *c_void); @@ -300,7 +297,7 @@ pub mod eabi { #[cfg(target_arch = "arm", not(test))] #[allow(visible_private_types)] pub mod eabi { - use uw = rt::libunwind; + use uw = libunwind; use libc::c_int; extern "C" { @@ -432,9 +429,9 @@ fn begin_unwind_inner(msg: Box<Any:Send>, // Now that we've run all the necessary unwind callbacks, we actually // perform the unwinding. If we don't have a task, then it's time to die // (hopefully someone printed something about this). - let task: Box<Task> = match Local::try_take() { + let mut task: Box<Task> = match Local::try_take() { Some(task) => task, - None => unsafe { intrinsics::abort() } + None => rust_fail(msg), }; if task.unwinder.unwinding { @@ -445,17 +442,13 @@ fn begin_unwind_inner(msg: Box<Any:Send>, rterrln!("task failed during unwinding. aborting."); unsafe { intrinsics::abort() } } + task.unwinder.unwinding = true; // Put the task back in TLS because the unwinding process may run code which // requires the task. We need a handle to its unwinder, however, so after // this we unsafely extract it and continue along. Local::put(task); - unsafe { - let task: *mut Task = Local::unsafe_borrow(); - (*task).unwinder.begin_unwind(msg); - } - task.name = name; - Local::put(task); + rust_fail(msg); } /// Register a callback to be invoked when a task unwinds. diff --git a/src/librustrt/util.rs b/src/librustrt/util.rs index 0b517bcc7fb..c08652cc08c 100644 --- a/src/librustrt/util.rs +++ b/src/librustrt/util.rs @@ -73,9 +73,7 @@ pub fn abort(args: &fmt::Arguments) -> ! { let mut w = BufWriter { buf: msg, pos: 0 }; let _ = write!(&mut w, "{}", args); let msg = str::from_utf8(w.buf.slice_to(w.pos)).unwrap_or("aborted"); - let msg = if msg.is_empty() { - "aborted" - } else { "aborted" }; + let msg = if msg.is_empty() {"aborted"} else {msg}; // Give some context to the message let hash = msg.bytes().fold(0, |accum, val| accum + (val as uint) ); diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs index cbbb961e048..e2122aea036 100644 --- a/src/librustuv/lib.rs +++ b/src/librustuv/lib.rs @@ -404,22 +404,23 @@ pub fn uv_error_to_io_error(uverr: UvError) -> IoError { let UvError(errcode) = uverr; IoError { code: match errcode { - uvll::EOF => io::EOF, - uvll::EACCES => io::ERROR_ACCESS_DENIED, - uvll::ECONNREFUSED => io::WSAECONNREFUSED, - uvll::ECONNRESET => io::WSAECONNRESET, - uvll::ENOTCONN => io::WSAENOTCONN, - uvll::ENOENT => io::ERROR_NOT_FOUND, - uvll::EPIPE => io::ERROR_BROKEN_PIPE, - uvll::ECONNABORTED => io::WSAECONNABORTED, - uvll::EADDRNOTAVAIL => io::WSAEADDRNOTAVAIL, + uvll::EOF => libc::EOF, + uvll::EACCES => libc::ERROR_ACCESS_DENIED, + uvll::ECONNREFUSED => libc::WSAECONNREFUSED, + uvll::ECONNRESET => libc::WSAECONNRESET, + uvll::ENOTCONN => libc::WSAENOTCONN, + uvll::ENOENT => libc::ERROR_FILE_NOT_FOUND, + uvll::EPIPE => libc::ERROR_NO_DATA, + uvll::ECONNABORTED => libc::WSAECONNABORTED, + uvll::EADDRNOTAVAIL => libc::WSAEADDRNOTAVAIL, uvll::ECANCELED => libc::ERROR_OPERATION_ABORTED, + uvll::EADDRINUSE => libc::WSAEADDRINUSE, err => { uvdebug!("uverr.code {}", err as int); // FIXME: Need to map remaining uv error types -1 } - }, + } as uint, extra: 0, detail: Some(uverr.desc()), } diff --git a/src/librustuv/uvll.rs b/src/librustuv/uvll.rs index 91c68147251..f6c6d6c9068 100644 --- a/src/librustuv/uvll.rs +++ b/src/librustuv/uvll.rs @@ -38,7 +38,8 @@ use std::rt::libc_heap::malloc_raw; use libc::uintptr_t; pub use self::errors::{EACCES, ECONNREFUSED, ECONNRESET, EPIPE, ECONNABORTED, - ECANCELED, EBADF, ENOTCONN, ENOENT, EADDRNOTAVAIL}; + ECANCELED, EBADF, ENOTCONN, ENOENT, EADDRNOTAVAIL, + EADDRINUSE}; pub static OK: c_int = 0; pub static EOF: c_int = -4095; @@ -61,6 +62,7 @@ pub mod errors { pub static ECANCELED: c_int = -4081; pub static EBADF: c_int = -4083; pub static EADDRNOTAVAIL: c_int = -4090; + pub static EADDRINUSE: c_int = -4091; } #[cfg(not(windows))] pub mod errors { @@ -77,6 +79,7 @@ pub mod errors { pub static ECANCELED : c_int = -libc::ECANCELED; pub static EBADF : c_int = -libc::EBADF; pub static EADDRNOTAVAIL : c_int = -libc::EADDRNOTAVAIL; + pub static EADDRINUSE : c_int = -libc::EADDRINUSE; } pub static PROCESS_SETUID: c_int = 1 << 0; diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 94d60cb3ce7..c72cc0ded9b 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -313,7 +313,8 @@ impl IoError { libc::ERROR_INVALID_NAME => (InvalidInput, "invalid file name"), libc::WSAECONNREFUSED => (ConnectionRefused, "connection refused"), libc::WSAECONNRESET => (ConnectionReset, "connection reset"), - libc::WSAEACCES => (PermissionDenied, "permission denied"), + libc::ERROR_ACCESS_DENIED | libc::WSAEACCES => + (PermissionDenied, "permission denied"), libc::WSAEWOULDBLOCK => { (ResourceUnavailable, "resource temporarily unavailable") } @@ -327,7 +328,7 @@ impl IoError { libc::WSAEINVAL => (InvalidInput, "invalid argument"), libc::ERROR_CALL_NOT_IMPLEMENTED => (IoUnavailable, "function not implemented"), - libc::ERROR_CALL_NOT_IMPLEMENTED => + libc::ERROR_INVALID_HANDLE => (MismatchedFileTypeForOperation, "invalid handle provided to function"), libc::ERROR_NOTHING_TO_TERMINATE => diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs index 8ce77faa296..6c773467553 100644 --- a/src/libstd/io/net/tcp.rs +++ b/src/libstd/io/net/tcp.rs @@ -982,7 +982,8 @@ mod test { match TcpListener::bind(ip_str.as_slice(), port).listen() { Ok(..) => fail!(), Err(e) => { - assert!(e.kind == ConnectionRefused || e.kind == OtherIoError); + assert!(e.kind == ConnectionRefused || e.kind == OtherIoError, + "unknown error: {} {}", e, e.kind); } } }) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index fe5fabef9d9..bac4d26b4e4 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -256,11 +256,6 @@ pub mod unstable; pub mod rt; mod failure; -#[doc(hidden)] -pub fn issue_14344_workaround() { // FIXME #14344 force linkage to happen correctly - libc::issue_14344_workaround(); -} - // A curious inner-module that's not exported that contains the binding // 'std' so that macro-expanded references to std::error and such // can be resolved within libstd. diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs index 4229e9ad32c..766901fa04f 100644 --- a/src/libstd/rt/backtrace.rs +++ b/src/libstd/rt/backtrace.rs @@ -603,6 +603,7 @@ mod imp { mod imp { use c_str::CString; use container::Container; + use intrinsics; use io::{IoResult, Writer}; use libc; use mem; @@ -610,11 +611,10 @@ mod imp { use option::{Some, None}; use path::Path; use result::{Ok, Err}; + use rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT}; + use slice::ImmutableVector; use str::StrSlice; use unstable::dynamic_lib::DynamicLibrary; - use intrinsics; - use unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT}; - use slice::ImmutableVector; #[allow(non_snake_case_functions)] extern "system" { diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index e8df7465a74..a68a632bc37 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -57,10 +57,11 @@ Several modules in `core` are clients of `rt`: use failure; use rustrt; -// TODO: dox +// Reexport some of our utilities which are expected by other crates. pub use self::util::{default_sched_threads, min_stack, running_on_valgrind}; -// TODO: dox +// Reexport functionality from librustrt and other crates underneath the +// standard library which work together to create the entire runtime. pub use alloc::{heap, libc_heap}; pub use rustrt::{task, local, mutex, exclusive, stack, args, rtio}; pub use rustrt::{Stdio, Stdout, Stderr, begin_unwind, begin_unwind_fmt}; diff --git a/src/libstd/task.rs b/src/libstd/task.rs index 55ebba69d90..9ee62ee3d81 100644 --- a/src/libstd/task.rs +++ b/src/libstd/task.rs @@ -182,14 +182,8 @@ impl TaskBuilder { }; if stdout.is_some() || stderr.is_some() { t.spawn_sibling(opts, proc() { - match stdout { - Some(handle) => { let _ = stdio::set_stdout(handle); } - None => {} - } - match stderr { - Some(handle) => { let _ = stdio::set_stderr(handle); } - None => {} - } + let _ = stdout.map(stdio::set_stdout); + let _ = stderr.map(stdio::set_stderr); f(); }); } else { diff --git a/src/libsync/mutex.rs b/src/libsync/mutex.rs index ee7fa525e79..bcf5a43fb6b 100644 --- a/src/libsync/mutex.rs +++ b/src/libsync/mutex.rs @@ -64,7 +64,7 @@ use std::rt::task::{BlockedTask, Task}; use std::rt::thread::Thread; use std::sync::atomics; use std::ty::Unsafe; -use std::unstable::mutex; +use std::rt::mutex; use q = mpsc_intrusive; diff --git a/src/test/run-pass/running-with-no-runtime.rs b/src/test/run-pass/running-with-no-runtime.rs index 1fe99336bc9..0ef48c99782 100644 --- a/src/test/run-pass/running-with-no-runtime.rs +++ b/src/test/run-pass/running-with-no-runtime.rs @@ -28,7 +28,7 @@ fn start(argc: int, argv: **u8) -> int { 4 => assert!(try(|| fail!()).is_err()), 5 => assert!(try(|| spawn(proc() {})).is_err()), 6 => assert!(Command::new("test").spawn().is_err()), - 7 => assert!(foo.get().is_some()), + 7 => assert!(foo.get().is_none()), 8 => assert!(try(|| { foo.replace(Some(3)); }).is_err()), _ => fail!() } @@ -49,6 +49,8 @@ fn main() { pass(Command::new(me).arg(&[4u8]).output().unwrap()); pass(Command::new(me).arg(&[5u8]).output().unwrap()); pass(Command::new(me).arg(&[6u8]).output().unwrap()); + pass(Command::new(me).arg(&[7u8]).output().unwrap()); + pass(Command::new(me).arg(&[8u8]).output().unwrap()); } fn pass(output: ProcessOutput) { diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs index 4034c2571cd..a9a6e25adf3 100644 --- a/src/test/run-pass/tcp-stress.rs +++ b/src/test/run-pass/tcp-stress.rs @@ -61,7 +61,7 @@ fn main() { for _ in range(0, 1000) { let tx = tx.clone(); let mut builder = TaskBuilder::new(); - builder.opts.stack_size = Some(32 * 1024); + builder.opts.stack_size = Some(64 * 1024); builder.spawn(proc() { let host = addr.ip.to_str(); let port = addr.port; |
