diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-12-31 10:20:31 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-12-31 10:20:31 -0800 |
| commit | aec67c2ee0f673ea7b0e21c2fe7e0f26a523d823 (patch) | |
| tree | 032a8ec1398c7334c20b791a4c4c460feb5e2c79 /src/libstd/sys | |
| parent | 582cba183f18eea5c40b6c035d63ad449a9e8604 (diff) | |
| download | rust-aec67c2ee0f673ea7b0e21c2fe7e0f26a523d823.tar.gz rust-aec67c2ee0f673ea7b0e21c2fe7e0f26a523d823.zip | |
Revert "std: Re-enable at_exit()"
This reverts commit 9e224c2bf18ebf8f871efb2e1aba43ed7970ebb7. Conflicts: src/libstd/sys/windows/os.rs
Diffstat (limited to 'src/libstd/sys')
32 files changed, 182 insertions, 118 deletions
diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs index 7093c417b11..9ef1c33312f 100644 --- a/src/libstd/sys/common/helper_thread.rs +++ b/src/libstd/sys/common/helper_thread.rs @@ -20,8 +20,6 @@ //! can be created in the future and there must be no active timers at that //! time. -#![macro_escape] - use prelude::*; use cell::UnsafeCell; @@ -70,17 +68,6 @@ struct RaceBox(helper_signal::signal); unsafe impl Send for RaceBox {} unsafe impl Sync for RaceBox {} -macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => ( - static $name: Helper<$m> = Helper { - lock: ::sync::MUTEX_INIT, - cond: ::sync::CONDVAR_INIT, - chan: ::cell::UnsafeCell { value: 0 as *mut Sender<$m> }, - signal: ::cell::UnsafeCell { value: 0 }, - initialized: ::cell::UnsafeCell { value: false }, - shutdown: ::cell::UnsafeCell { value: false }, - }; -) } - impl<M: Send> Helper<M> { /// Lazily boots a helper thread, becoming a no-op if the helper has already /// been spawned. @@ -97,7 +84,7 @@ impl<M: Send> Helper<M> { { unsafe { let _guard = self.lock.lock().unwrap(); - if *self.chan.get() as uint == 0 { + if !*self.initialized.get() { let (tx, rx) = channel(); *self.chan.get() = mem::transmute(box tx); let (receive, send) = helper_signal::new(); @@ -106,17 +93,15 @@ impl<M: Send> Helper<M> { let receive = RaceBox(receive); let t = f(); - Thread::spawn(move || { + Thread::spawn(move |:| { helper(receive.0, rx, t); let _g = self.lock.lock().unwrap(); *self.shutdown.get() = true; self.cond.notify_one() }).detach(); - rt::at_exit(move || { self.shutdown() }); + rt::at_exit(move|:| { self.shutdown() }); *self.initialized.get() = true; - } else if *self.chan.get() as uint == 1 { - panic!("cannot continue usage after shutdown"); } } } @@ -131,9 +116,7 @@ impl<M: Send> Helper<M> { // Must send and *then* signal to ensure that the child receives the // message. Otherwise it could wake up and go to sleep before we // send the message. - assert!(*self.chan.get() as uint != 0); - assert!(*self.chan.get() as uint != 1, - "cannot continue usage after shutdown"); + assert!(!self.chan.get().is_null()); (**self.chan.get()).send(msg); helper_signal::signal(*self.signal.get() as helper_signal::signal); } @@ -146,13 +129,9 @@ impl<M: Send> Helper<M> { // returns. let mut guard = self.lock.lock().unwrap(); - let ptr = *self.chan.get(); - if ptr as uint == 1 { - panic!("cannot continue usage after shutdown"); - } // Close the channel by destroying it let chan: Box<Sender<M>> = mem::transmute(*self.chan.get()); - *self.chan.get() = 1 as *mut Sender<M>; + *self.chan.get() = 0 as *mut Sender<M>; drop(chan); helper_signal::signal(*self.signal.get() as helper_signal::signal); diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs index 6b2b325e638..dc0ad08cdbe 100644 --- a/src/libstd/sys/common/mod.rs +++ b/src/libstd/sys/common/mod.rs @@ -9,7 +9,7 @@ // except according to those terms. #![allow(missing_docs)] -#![macro_escape] +#![allow(dead_code)] use io::{mod, IoError, IoResult}; use prelude::*; diff --git a/src/libstd/sys/common/mutex.rs b/src/libstd/sys/common/mutex.rs index 322d2f202f7..567c26956ef 100644 --- a/src/libstd/sys/common/mutex.rs +++ b/src/libstd/sys/common/mutex.rs @@ -29,7 +29,6 @@ impl Mutex { /// Behavior is undefined if the mutex is moved after the first method is /// called on the mutex. #[inline] - #[allow(dead_code)] // sys is not exported yet pub unsafe fn new() -> Mutex { Mutex(imp::Mutex::new()) } /// Lock the mutex blocking the current thread until it is available. diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index 552d1c201da..87ec20fbef8 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -23,9 +23,7 @@ use io::{IoResult, IoError}; use sys::{mod, retry, c, sock_t, last_error, last_net_error, last_gai_error, close_sock, wrlen, msglen_t, os, wouldblock, set_nonblocking, timer, ms_to_timeval, decode_error_detailed}; -use sync::Mutex; -#[cfg(not(target_os = "linux"))] -use sync::MutexGuard; +use sync::{Mutex, MutexGuard}; use sys_common::{mod, keep_going, short_write, timeout}; use prelude::*; use cmp; @@ -613,13 +611,11 @@ impl Drop for Inner { fn drop(&mut self) { unsafe { close_sock(self.fd); } } } -#[cfg(not(target_os = "linux"))] pub struct Guard<'a> { pub fd: sock_t, pub guard: MutexGuard<'a, ()>, } -#[cfg(not(target_os = "linux"))] #[unsafe_destructor] impl<'a> Drop for Guard<'a> { fn drop(&mut self) { diff --git a/src/libstd/sys/common/rwlock.rs b/src/libstd/sys/common/rwlock.rs index b7c4cfcd0f5..df016b9e293 100644 --- a/src/libstd/sys/common/rwlock.rs +++ b/src/libstd/sys/common/rwlock.rs @@ -26,7 +26,6 @@ impl RWLock { /// Usage of an RWLock is undefined if it is moved after its first use (any /// function calls below). #[inline] - #[allow(dead_code)] // sys is not exported yet pub unsafe fn new() -> RWLock { RWLock(imp::RWLock::new()) } /// Acquire shared access to the underlying lock, blocking the current diff --git a/src/libstd/sys/common/stack.rs b/src/libstd/sys/common/stack.rs index 1966a9544e1..2a88e20c8fa 100644 --- a/src/libstd/sys/common/stack.rs +++ b/src/libstd/sys/common/stack.rs @@ -121,6 +121,37 @@ pub unsafe fn record_os_managed_stack_bounds(stack_lo: uint, _stack_hi: uint) { record_sp_limit(stack_lo + RED_ZONE); } +#[inline(always)] +pub unsafe fn record_rust_managed_stack_bounds(stack_lo: uint, stack_hi: uint) { + // When the old runtime had segmented stacks, it used a calculation that was + // "limit + RED_ZONE + FUDGE". The red zone was for things like dynamic + // symbol resolution, llvm function calls, etc. In theory this red zone + // value is 0, but it matters far less when we have gigantic stacks because + // we don't need to be so exact about our stack budget. The "fudge factor" + // was because LLVM doesn't emit a stack check for functions < 256 bytes in + // size. Again though, we have giant stacks, so we round all these + // calculations up to the nice round number of 20k. + record_sp_limit(stack_lo + RED_ZONE); + + return target_record_stack_bounds(stack_lo, stack_hi); + + #[cfg(not(windows))] #[inline(always)] + unsafe fn target_record_stack_bounds(_stack_lo: uint, _stack_hi: uint) {} + + #[cfg(all(windows, target_arch = "x86"))] #[inline(always)] + unsafe fn target_record_stack_bounds(stack_lo: uint, stack_hi: uint) { + // stack range is at TIB: %fs:0x04 (top) and %fs:0x08 (bottom) + asm!("mov $0, %fs:0x04" :: "r"(stack_hi) :: "volatile"); + asm!("mov $0, %fs:0x08" :: "r"(stack_lo) :: "volatile"); + } + #[cfg(all(windows, target_arch = "x86_64"))] #[inline(always)] + unsafe fn target_record_stack_bounds(stack_lo: uint, stack_hi: uint) { + // stack range is at TIB: %gs:0x08 (top) and %gs:0x10 (bottom) + asm!("mov $0, %gs:0x08" :: "r"(stack_hi) :: "volatile"); + asm!("mov $0, %gs:0x10" :: "r"(stack_lo) :: "volatile"); + } +} + /// Records the current limit of the stack as specified by `end`. /// /// This is stored in an OS-dependent location, likely inside of the thread diff --git a/src/libstd/sys/common/thread_info.rs b/src/libstd/sys/common/thread_info.rs index f32c1ea3658..dc21feb17a8 100644 --- a/src/libstd/sys/common/thread_info.rs +++ b/src/libstd/sys/common/thread_info.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![allow(dead_code)] // stack_guard isn't used right now on all platforms - use core::prelude::*; use thread::Thread; @@ -17,6 +15,10 @@ use cell::RefCell; use string::String; struct ThreadInfo { + // This field holds the known bounds of the stack in (lo, hi) + // form. Not all threads necessarily know their precise bounds, + // hence this is optional. + stack_bounds: (uint, uint), stack_guard: uint, thread: Thread, } @@ -33,6 +35,7 @@ impl ThreadInfo { THREAD_INFO.with(|c| { if c.borrow().is_none() { *c.borrow_mut() = Some(ThreadInfo { + stack_bounds: (0, 0), stack_guard: 0, thread: NewThread::new(None), }) @@ -50,9 +53,10 @@ pub fn stack_guard() -> uint { ThreadInfo::with(|info| info.stack_guard) } -pub fn set(stack_guard: uint, thread: Thread) { +pub fn set(stack_bounds: (uint, uint), stack_guard: uint, thread: Thread) { THREAD_INFO.with(|c| assert!(c.borrow().is_none())); THREAD_INFO.with(move |c| *c.borrow_mut() = Some(ThreadInfo{ + stack_bounds: stack_bounds, stack_guard: stack_guard, thread: thread, })); diff --git a/src/libstd/sys/common/thread_local.rs b/src/libstd/sys/common/thread_local.rs index cc69fbceacb..fe7a7d8d037 100644 --- a/src/libstd/sys/common/thread_local.rs +++ b/src/libstd/sys/common/thread_local.rs @@ -55,11 +55,11 @@ //! ``` #![allow(non_camel_case_types)] -#![allow(dead_code)] // sys isn't exported yet use prelude::*; use sync::atomic::{mod, AtomicUint}; +use sync::{Mutex, Once, ONCE_INIT}; use sys::thread_local as imp; @@ -140,6 +140,9 @@ pub const INIT_INNER: StaticKeyInner = StaticKeyInner { key: atomic::INIT_ATOMIC_UINT, }; +static INIT_KEYS: Once = ONCE_INIT; +static mut KEYS: *mut Mutex<Vec<imp::Key>> = 0 as *mut _; + impl StaticKey { /// Gets the value associated with this TLS key /// diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs index 0ec34fb1318..ddae9a132c3 100644 --- a/src/libstd/sys/unix/backtrace.rs +++ b/src/libstd/sys/unix/backtrace.rs @@ -83,12 +83,12 @@ /// to symbols. This is a bit of a hokey implementation as-is, but it works for /// all unix platforms we support right now, so it at least gets the job done. -use prelude::*; - use c_str::CString; -use io::IoResult; +use io::{IoResult, Writer}; use libc; use mem; +use option::Option::{mod, Some, None}; +use result::Result::{Ok, Err}; use sync::{StaticMutex, MUTEX_INIT}; use sys_common::backtrace::*; @@ -151,7 +151,7 @@ pub fn write(w: &mut Writer) -> IoResult<()> { // I/O done here is blocking I/O, not green I/O, so we don't have to // worry about this being a native vs green mutex. static LOCK: StaticMutex = MUTEX_INIT; - let _g = LOCK.lock(); + let _g = unsafe { LOCK.lock() }; try!(writeln!(w, "stack backtrace:")); @@ -241,8 +241,12 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> { #[cfg(not(any(target_os = "macos", target_os = "ios")))] fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> { + use iter::{Iterator, IteratorExt}; use os; + use path::GenericPath; + use ptr::PtrExt; use ptr; + use slice::SliceExt; //////////////////////////////////////////////////////////////////////// // libbacktrace.h API diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index dd4141de998..c82dacf1e44 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -10,14 +10,30 @@ #![allow(missing_docs)] #![allow(non_camel_case_types)] +#![allow(unused_imports)] +#![allow(dead_code)] +#![allow(unused_unsafe)] +#![allow(unused_mut)] extern crate libc; +use num; use num::{Int, SignedInt}; use prelude::*; use io::{mod, IoResult, IoError}; use sys_common::mkerr_libc; +macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => ( + static $name: Helper<$m> = Helper { + lock: ::sync::MUTEX_INIT, + cond: ::sync::CONDVAR_INIT, + chan: ::cell::UnsafeCell { value: 0 as *mut Sender<$m> }, + signal: ::cell::UnsafeCell { value: 0 }, + initialized: ::cell::UnsafeCell { value: false }, + shutdown: ::cell::UnsafeCell { value: false }, + }; +) } + pub mod backtrace; pub mod c; pub mod ext; diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs index c9cb46b0289..81f8659d6ae 100644 --- a/src/libstd/sys/unix/mutex.rs +++ b/src/libstd/sys/unix/mutex.rs @@ -11,6 +11,7 @@ use cell::UnsafeCell; use kinds::Sync; use sys::sync as ffi; +use sys_common::mutex; pub struct Mutex { inner: UnsafeCell<ffi::pthread_mutex_t> } @@ -25,7 +26,6 @@ pub const MUTEX_INIT: Mutex = Mutex { unsafe impl Sync for Mutex {} -#[allow(dead_code)] // sys isn't exported yet impl Mutex { #[inline] pub unsafe fn new() -> Mutex { diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 446960ab92f..cafe52f8403 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -10,16 +10,17 @@ //! Implementation of `std::os` functionality for unix systems -#![allow(unused_imports)] // lots of cfg code here - use prelude::*; +use error::{FromError, Error}; +use fmt; use io::{IoError, IoResult}; -use libc::{mod, c_int, c_char}; -use os; +use libc::{mod, c_int, c_char, c_void}; use path::BytesContainer; use ptr; +use sync::atomic::{AtomicInt, INIT_ATOMIC_INT, SeqCst}; use sys::fs::FileDesc; +use os; use os::TMPBUF_SZ; diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index 3b868065f8f..868b460aa5e 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -145,7 +145,7 @@ impl UnixStream { fn lock_nonblocking<'a>(&'a self) -> Guard<'a> { let ret = Guard { fd: self.fd(), - guard: self.inner.lock.lock().unwrap(), + guard: unsafe { self.inner.lock.lock().unwrap() }, }; assert!(set_nonblocking(self.fd(), true).is_ok()); ret diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index 48df8c4eced..835f4279d9b 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -11,7 +11,7 @@ use self::Req::*; use libc::{mod, pid_t, c_void, c_int}; use c_str::CString; -use io::{IoResult, EndOfFile}; +use io::{mod, IoResult, IoError, EndOfFile}; use mem; use os; use ptr; @@ -327,7 +327,7 @@ impl Process { // The actual communication between the helper thread and this thread is // quite simple, just a channel moving data around. - HELPER.boot(register_sigchld, waitpid_helper); + unsafe { HELPER.boot(register_sigchld, waitpid_helper) } match self.try_wait() { Some(ret) => return Ok(ret), @@ -335,7 +335,7 @@ impl Process { } let (tx, rx) = channel(); - HELPER.send(NewChild(self.pid, tx, deadline)); + unsafe { HELPER.send(NewChild(self.pid, tx, deadline)); } return match rx.recv_opt() { Ok(e) => Ok(e), Err(()) => Err(timeout("wait timed out")), @@ -419,15 +419,8 @@ impl Process { Ok(NewChild(pid, tx, deadline)) => { active.push((pid, tx, deadline)); } - // Once we've been disconnected it means the main - // thread is exiting (at_exit has run). We could - // still have active waiter for other threads, so - // we're just going to drop them all on the floor. - // This means that they won't receive a "you're - // done" message in which case they'll be considered - // as timed out, but more generally errors will - // start propagating. Err(comm::Disconnected) => { + assert!(active.len() == 0); break 'outer; } Err(comm::Empty) => break, diff --git a/src/libstd/sys/unix/rwlock.rs b/src/libstd/sys/unix/rwlock.rs index 4f9b06685ec..0d63ff14ff2 100644 --- a/src/libstd/sys/unix/rwlock.rs +++ b/src/libstd/sys/unix/rwlock.rs @@ -17,7 +17,6 @@ pub const RWLOCK_INIT: RWLock = RWLock { inner: UnsafeCell { value: ffi::PTHREAD_RWLOCK_INITIALIZER }, }; -#[allow(dead_code)] // sys isn't exported yet impl RWLock { #[inline] pub unsafe fn new() -> RWLock { diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs index f1d7f1784d0..bcbbb8766b7 100644 --- a/src/libstd/sys/unix/stack_overflow.rs +++ b/src/libstd/sys/unix/stack_overflow.rs @@ -34,6 +34,7 @@ impl Drop for Handler { #[cfg(any(target_os = "linux", target_os = "macos"))] mod imp { + use core::prelude::*; use sys_common::stack; use super::Handler; diff --git a/src/libstd/sys/unix/tcp.rs b/src/libstd/sys/unix/tcp.rs index 696d3fb676d..e2a78947e16 100644 --- a/src/libstd/sys/unix/tcp.rs +++ b/src/libstd/sys/unix/tcp.rs @@ -135,6 +135,10 @@ impl TcpAcceptor { Err(sys_common::eof()) } + pub fn socket_name(&mut self) -> IoResult<ip::SocketAddr> { + net::sockname(self.fd(), libc::getsockname) + } + pub fn set_timeout(&mut self, timeout: Option<u64>) { self.deadline = timeout.map(|a| sys::timer::now() + a).unwrap_or(0); } diff --git a/src/libstd/sys/unix/timer.rs b/src/libstd/sys/unix/timer.rs index 150ec6aad8a..c0ef89666c0 100644 --- a/src/libstd/sys/unix/timer.rs +++ b/src/libstd/sys/unix/timer.rs @@ -100,7 +100,7 @@ pub fn now() -> u64 { fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) { let mut set: c::fd_set = unsafe { mem::zeroed() }; - let fd = FileDesc::new(input, true); + let mut fd = FileDesc::new(input, true); let mut timeout: libc::timeval = unsafe { mem::zeroed() }; // active timers are those which are able to be selected upon (and it's a @@ -168,15 +168,8 @@ fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) { 1 => { loop { match messages.try_recv() { - // Once we've been disconnected it means the main thread - // is exiting (at_exit has run). We could still have - // active timers for other threads, so we're just going - // to drop them all on the floor. This is all we can - // really do, however, to prevent resource leakage. The - // remaining timers will likely start panicking quickly - // as they attempt to re-use this thread but are - // disallowed to do so. Err(comm::Disconnected) => { + assert!(active.len() == 0); break 'outer; } diff --git a/src/libstd/sys/unix/tty.rs b/src/libstd/sys/unix/tty.rs index d05047a220f..28c17fd4966 100644 --- a/src/libstd/sys/unix/tty.rs +++ b/src/libstd/sys/unix/tty.rs @@ -43,4 +43,5 @@ impl TTY { pub fn get_winsize(&mut self) -> IoResult<(int, int)> { Err(sys_common::unimpl()) } + pub fn isatty(&self) -> bool { false } } diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs index e5a37e5651b..42c8f7705e1 100644 --- a/src/libstd/sys/windows/backtrace.rs +++ b/src/libstd/sys/windows/backtrace.rs @@ -7,22 +7,19 @@ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. - -//! As always, windows has something very different than unix, we mainly want -//! to avoid having to depend too much on libunwind for windows. -//! -//! If you google around, you'll find a fair bit of references to built-in -//! functions to get backtraces on windows. It turns out that most of these are -//! in an external library called dbghelp. I was unable to find this library -//! via `-ldbghelp`, but it is apparently normal to do the `dlopen` equivalent -//! of it. -//! -//! You'll also find that there's a function called CaptureStackBackTrace -//! mentioned frequently (which is also easy to use), but sadly I didn't have a -//! copy of that function in my mingw install (maybe it was broken?). Instead, -//! this takes the route of using StackWalk64 in order to walk the stack. - -#![allow(dead_code)] // constants/fields aren't always used on all platforms +/// As always, windows has something very different than unix, we mainly want +/// to avoid having to depend too much on libunwind for windows. +/// +/// If you google around, you'll find a fair bit of references to built-in +/// functions to get backtraces on windows. It turns out that most of these are +/// in an external library called dbghelp. I was unable to find this library +/// via `-ldbghelp`, but it is apparently normal to do the `dlopen` equivalent +/// of it. +/// +/// You'll also find that there's a function called CaptureStackBackTrace +/// mentioned frequently (which is also easy to use), but sadly I didn't have a +/// copy of that function in my mingw install (maybe it was broken?). Instead, +/// this takes the route of using StackWalk64 in order to walk the stack. use c_str::CString; use intrinsics; @@ -297,7 +294,7 @@ pub fn write(w: &mut Writer) -> IoResult<()> { // According to windows documentation, all dbghelp functions are // single-threaded. static LOCK: StaticMutex = MUTEX_INIT; - let _g = LOCK.lock(); + let _g = unsafe { LOCK.lock() }; // Open up dbghelp.dll, we don't link to it explicitly because it can't // always be found. Additionally, it's nice having fewer dependencies. diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index 0aa7e539d78..06259d61fcb 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -15,6 +15,7 @@ #![allow(non_camel_case_types)] use libc; +use prelude::*; pub const WSADESCRIPTION_LEN: uint = 256; pub const WSASYS_STATUS_LEN: uint = 128; diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index 523d9e9a3c2..3ad439078b9 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -10,17 +10,21 @@ //! Blocking Windows-based file I/O +use alloc::arc::Arc; use libc::{mod, c_int}; -use io; +use c_str::CString; use mem; -use ptr; use sys::os::fill_utf16_buf_and_decode; +use path; +use ptr; +use str; +use io; use prelude::*; use sys; use sys::os; -use sys_common::{unimpl, mkerr_libc}; +use sys_common::{keep_going, eof, mkerr_libc}; use io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode}; use io::{IoResult, IoError, FileStat, SeekStyle}; @@ -441,7 +445,7 @@ pub fn stat(p: &Path) -> IoResult<FileStat> { // FIXME: move this to platform-specific modules (for now)? pub fn lstat(_p: &Path) -> IoResult<FileStat> { // FIXME: implementation is missing - Err(unimpl()) + Err(super::unimpl()) } pub fn utime(p: &Path, atime: u64, mtime: u64) -> IoResult<()> { diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 3fae03146f3..57c284ed6a3 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -11,14 +11,30 @@ #![allow(missing_docs)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] +#![allow(unused_imports)] +#![allow(dead_code)] +#![allow(unused_unsafe)] +#![allow(unused_mut)] extern crate libc; +use num; use mem; use prelude::*; use io::{mod, IoResult, IoError}; use sync::{Once, ONCE_INIT}; +macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => ( + static $name: Helper<$m> = Helper { + lock: ::sync::MUTEX_INIT, + cond: ::sync::CONDVAR_INIT, + chan: ::cell::UnsafeCell { value: 0 as *mut Sender<$m> }, + signal: ::cell::UnsafeCell { value: 0 }, + initialized: ::cell::UnsafeCell { value: false }, + shutdown: ::cell::UnsafeCell { value: false }, + }; +) } + pub mod backtrace; pub mod c; pub mod ext; @@ -164,6 +180,14 @@ pub fn init_net() { } } +pub fn unimpl() -> IoError { + IoError { + kind: io::IoUnavailable, + desc: "operation is not implemented", + detail: None, + } +} + pub fn to_utf16(s: Option<&str>) -> IoResult<Vec<u16>> { match s { Some(s) => Ok({ diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index 28eca9163f6..e7194df7ac3 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -15,6 +15,7 @@ use prelude::*; +use fmt; use io::{IoResult, IoError}; use iter::repeat; use libc::{c_int, c_void}; diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index 8b2fc3d9fb5..fc3640f2604 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -365,7 +365,7 @@ impl UnixStream { // acquire the lock. // // See comments in close_read() about why this lock is necessary. - let guard = self.inner.lock.lock(); + let guard = unsafe { self.inner.lock.lock() }; if self.read_closed() { return Err(eof()) } @@ -441,7 +441,7 @@ impl UnixStream { // going after we woke up. // // See comments in close_read() about why this lock is necessary. - let guard = self.inner.lock.lock(); + let guard = unsafe { self.inner.lock.lock() }; if self.write_closed() { return Err(epipe()) } @@ -516,14 +516,14 @@ impl UnixStream { // close_read() between steps 1 and 2. By atomically executing steps 1 // and 2 with a lock with respect to close_read(), we're guaranteed that // no thread will erroneously sit in a read forever. - let _guard = self.inner.lock.lock(); + let _guard = unsafe { self.inner.lock.lock() }; self.inner.read_closed.store(true, atomic::SeqCst); self.cancel_io() } pub fn close_write(&mut self) -> IoResult<()> { // see comments in close_read() for why this lock is necessary - let _guard = self.inner.lock.lock(); + let _guard = unsafe { self.inner.lock.lock() }; self.inner.write_closed.store(true, atomic::SeqCst); self.cancel_io() } diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index 0c5a0eb6bb9..0c2c76077dd 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -8,24 +8,25 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use prelude::*; - -use libc::{pid_t, c_void}; +use libc::{pid_t, c_void, c_int}; use libc; use c_str::CString; use io; use mem; use os; use ptr; -use io::process::{ProcessExit, ExitStatus}; +use prelude::*; +use io::process::{ProcessExit, ExitStatus, ExitSignal}; use collections; use path::BytesContainer; use hash::Hash; use io::{IoResult, IoError}; -use sys::timer; +use sys::fs; +use sys::{mod, retry, c, wouldblock, set_nonblocking, ms_to_timeval, timer}; use sys::fs::FileDesc; -use sys_common::{AsInner, timeout}; +use sys_common::helper_thread::Helper; +use sys_common::{AsInner, mkerr_libc, timeout}; use io::fs::PathExtensions; @@ -120,6 +121,8 @@ impl Process { use libc::funcs::extra::msvcrt::get_osfhandle; use mem; + use iter::{Iterator, IteratorExt}; + use str::StrExt; if cfg.gid().is_some() || cfg.uid().is_some() { return Err(IoError { diff --git a/src/libstd/sys/windows/stack_overflow.rs b/src/libstd/sys/windows/stack_overflow.rs index ab092f5a243..bdf2e0bccb1 100644 --- a/src/libstd/sys/windows/stack_overflow.rs +++ b/src/libstd/sys/windows/stack_overflow.rs @@ -14,7 +14,7 @@ use ptr; use mem; use libc; use libc::types::os::arch::extra::{LPVOID, DWORD, LONG, BOOL}; -use sys_common::stack; +use sys_common::{stack, thread_info}; pub struct Handler { _data: *mut libc::c_void @@ -30,6 +30,14 @@ impl Drop for Handler { fn drop(&mut self) {} } +// get_task_info is called from an exception / signal handler. +// It returns the guard page of the current task or 0 if that +// guard page doesn't exist. None is returned if there's currently +// no local task. +unsafe fn get_task_guard_page() -> uint { + thread_info::stack_guard() +} + // This is initialized in init() and only read from after static mut PAGE_SIZE: uint = 0; diff --git a/src/libstd/sys/windows/tcp.rs b/src/libstd/sys/windows/tcp.rs index 339c724d9a9..513c1d38e36 100644 --- a/src/libstd/sys/windows/tcp.rs +++ b/src/libstd/sys/windows/tcp.rs @@ -14,10 +14,11 @@ use libc; use mem; use ptr; use prelude::*; -use super::{last_error, last_net_error, sock_t}; +use super::{last_error, last_net_error, retry, sock_t}; use sync::{Arc, atomic}; +use sys::fs::FileDesc; use sys::{mod, c, set_nonblocking, wouldblock, timer}; -use sys_common::{timeout, eof, net}; +use sys_common::{mod, timeout, eof, net}; pub use sys_common::net::TcpStream; @@ -204,6 +205,10 @@ impl TcpAcceptor { Err(eof()) } + pub fn socket_name(&mut self) -> IoResult<ip::SocketAddr> { + net::sockname(self.socket(), libc::getsockname) + } + pub fn set_timeout(&mut self, timeout: Option<u64>) { self.deadline = timeout.map(|a| timer::now() + a).unwrap_or(0); } diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs index 59ab5f5c4d9..4498f56c00a 100644 --- a/src/libstd/sys/windows/thread.rs +++ b/src/libstd/sys/windows/thread.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use core::prelude::*; + use boxed::Box; use cmp; use mem; diff --git a/src/libstd/sys/windows/thread_local.rs b/src/libstd/sys/windows/thread_local.rs index 4ac57e37117..60b0d584db3 100644 --- a/src/libstd/sys/windows/thread_local.rs +++ b/src/libstd/sys/windows/thread_local.rs @@ -137,9 +137,9 @@ unsafe fn init_dtors() { rt::at_exit(move|| { DTOR_LOCK.lock(); let dtors = DTORS; - DTORS = 1 as *mut _; + DTORS = 0 as *mut _; mem::transmute::<_, Box<Vec<(Key, Dtor)>>>(dtors); - assert!(DTORS as uint == 1); // can't re-init after destructing + assert!(DTORS.is_null()); // can't re-init after destructing DTOR_LOCK.unlock(); }); } @@ -147,9 +147,6 @@ unsafe fn init_dtors() { unsafe fn register_dtor(key: Key, dtor: Dtor) { DTOR_LOCK.lock(); init_dtors(); - assert!(DTORS as uint != 0); - assert!(DTORS as uint != 1, - "cannot create new TLS keys after the main thread has exited"); (*DTORS).push((key, dtor)); DTOR_LOCK.unlock(); } @@ -157,9 +154,6 @@ unsafe fn register_dtor(key: Key, dtor: Dtor) { unsafe fn unregister_dtor(key: Key) -> bool { DTOR_LOCK.lock(); init_dtors(); - assert!(DTORS as uint != 0); - assert!(DTORS as uint != 1, - "cannot unregister destructors after the main thread has exited"); let ret = { let dtors = &mut *DTORS; let before = dtors.len(); @@ -238,7 +232,6 @@ unsafe extern "system" fn on_tls_callback(h: LPVOID, } } -#[allow(dead_code)] // not actually dead unsafe fn run_dtors() { let mut any_run = true; for _ in range(0, 5i) { diff --git a/src/libstd/sys/windows/timer.rs b/src/libstd/sys/windows/timer.rs index c0e67642a64..874838950cd 100644 --- a/src/libstd/sys/windows/timer.rs +++ b/src/libstd/sys/windows/timer.rs @@ -26,6 +26,8 @@ use libc; use ptr; use comm; +use sys::c; +use sys::fs::FileDesc; use sys_common::helper_thread::Helper; use prelude::*; use io::IoResult; @@ -78,10 +80,9 @@ fn helper(input: libc::HANDLE, messages: Receiver<Req>, _: ()) { None => {} } } - // See the comment in unix::timer for why we don't have any - // asserts here and why we're likely just leaving timers on - // the floor as we exit. Err(comm::Disconnected) => { + assert_eq!(objs.len(), 1); + assert_eq!(chans.len(), 0); break 'outer; } Err(..) => break diff --git a/src/libstd/sys/windows/tty.rs b/src/libstd/sys/windows/tty.rs index 415524733ff..a88d11eed22 100644 --- a/src/libstd/sys/windows/tty.rs +++ b/src/libstd/sys/windows/tty.rs @@ -26,6 +26,7 @@ //! to working in raw UTF-16, with such a wrapper around it. use super::c::{ReadConsoleW, WriteConsoleW, GetConsoleMode, SetConsoleMode}; +use super::c::{ERROR_ILLEGAL_CHARACTER}; use super::c::{ENABLE_ECHO_INPUT, ENABLE_EXTENDED_FLAGS}; use super::c::{ENABLE_INSERT_MODE, ENABLE_LINE_INPUT}; use super::c::{ENABLE_PROCESSED_INPUT, ENABLE_QUICK_EDIT_MODE}; @@ -38,8 +39,6 @@ use prelude::*; use ptr; use str::from_utf8; -use sys_common::unimpl; - fn invalid_encoding() -> IoError { IoError { kind: io::InvalidInput, @@ -151,8 +150,11 @@ impl TTY { // Make a CONSOLE_SCREEN_BUFFER_INFO // Call GetConsoleScreenBufferInfo // Maybe call GetLargestConsoleWindowSize instead? - Err(unimpl()) + Err(super::unimpl()) } + + // Let us magically declare this as a TTY + pub fn isatty(&self) -> bool { true } } impl Drop for TTY { |
