about summary refs log tree commit diff
path: root/src/libstd/sys/windows
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-03-17 17:15:54 +0000
committerbors <bors@rust-lang.org>2015-03-17 17:15:54 +0000
commitbfac337daab9b86971bcb3db61382ac44f94621c (patch)
tree34bc72817ddffae38dde0fa30b8f35a0bc92e1d3 /src/libstd/sys/windows
parentc64d671671aea2e44ee7fc6eb00ee75fc30ed7b9 (diff)
parent04cf5344111c357ad80335b88709281bb4bfaa0a (diff)
downloadrust-bfac337daab9b86971bcb3db61382ac44f94621c.tar.gz
rust-bfac337daab9b86971bcb3db61382ac44f94621c.zip
Auto merge of #23330 - alexcrichton:thread-sleep, r=aturon
This function is the current replacement for `std::old_io::timer` which will
soon be deprecated. This function is unstable and has its own feature gate as it
does not yet have an RFC nor has it existed for very long.
Diffstat (limited to 'src/libstd/sys/windows')
-rw-r--r--src/libstd/sys/windows/thread.rs66
1 files changed, 36 insertions, 30 deletions
diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs
index aa22b6b1307..d1d4ad90081 100644
--- a/src/libstd/sys/windows/thread.rs
+++ b/src/libstd/sys/windows/thread.rs
@@ -10,43 +10,28 @@
 
 use prelude::v1::*;
 
-use boxed;
 use cmp;
 use io;
-use ptr;
-use libc;
+use libc::{self, c_void};
 use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES, SIZE_T, BOOL,
                                    LPVOID, DWORD, LPDWORD, HANDLE};
-use thunk::Thunk;
+use mem;
+use ptr;
 use sys_common::stack::RED_ZONE;
 use sys_common::thread::*;
+use thunk::Thunk;
+use time::Duration;
 
 pub type rust_thread = HANDLE;
-pub type rust_thread_return = DWORD;
-
-pub type StartFn = extern "system" fn(*mut libc::c_void) -> rust_thread_return;
-
-#[no_stack_check]
-pub extern "system" fn thread_start(main: *mut libc::c_void) -> rust_thread_return {
-    return start_thread(main);
-}
 
 pub mod guard {
-    pub unsafe fn main() -> uint {
-        0
-    }
-
-    pub unsafe fn current() -> uint {
-        0
-    }
-
-    pub unsafe fn init() {
-    }
+    pub unsafe fn main() -> uint { 0 }
+    pub unsafe fn current() -> uint { 0 }
+    pub unsafe fn init() {}
 }
 
-pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> {
-    let raw_p = boxed::into_raw(box p);
-    let arg = raw_p as *mut libc::c_void;
+pub unsafe fn create(stack: usize, p: Thunk) -> io::Result<rust_thread> {
+    let p = box p;
     // FIXME On UNIX, we guard against stack sizes that are too small but
     // that's because pthreads enforces that stacks are at least
     // PTHREAD_STACK_MIN bytes big.  Windows has no such lower limit, it's
@@ -58,14 +43,20 @@ pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> {
     // 20 kB red zone, that makes for a 64 kB minimum stack.
     let stack_size = (cmp::max(stack, RED_ZONE) + 0xfffe) & (-0xfffe - 1);
     let ret = CreateThread(ptr::null_mut(), stack_size as libc::size_t,
-                           thread_start, arg, 0, ptr::null_mut());
+                           thread_start, &*p as *const _ as *mut _,
+                           0, ptr::null_mut());
 
-    if ret as uint == 0 {
-        // be sure to not leak the closure
-        let _p: Box<Thunk> = Box::from_raw(raw_p);
+    return if ret as usize == 0 {
         Err(io::Error::last_os_error())
     } else {
+        mem::forget(p); // ownership passed to CreateThread
         Ok(ret)
+    };
+
+    #[no_stack_check]
+    extern "system" fn thread_start(main: *mut libc::c_void) -> DWORD {
+        start_thread(main);
+        0
     }
 }
 
@@ -92,14 +83,29 @@ pub unsafe fn yield_now() {
     SwitchToThread();
 }
 
+pub fn sleep(dur: Duration) {
+    unsafe {
+        if dur < Duration::zero() {
+            return yield_now()
+        }
+        let ms = dur.num_milliseconds();
+        // if we have a fractional number of milliseconds then add an extra
+        // millisecond to sleep for
+        let extra = dur - Duration::milliseconds(ms);
+        let ms = ms + if extra.is_zero() {0} else {1};
+        Sleep(ms as DWORD);
+    }
+}
+
 #[allow(non_snake_case)]
 extern "system" {
     fn CreateThread(lpThreadAttributes: LPSECURITY_ATTRIBUTES,
                     dwStackSize: SIZE_T,
-                    lpStartAddress: StartFn,
+                    lpStartAddress: extern "system" fn(*mut c_void) -> DWORD,
                     lpParameter: LPVOID,
                     dwCreationFlags: DWORD,
                     lpThreadId: LPDWORD) -> HANDLE;
     fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;
     fn SwitchToThread() -> BOOL;
+    fn Sleep(dwMilliseconds: DWORD);
 }