From 101aaa38616411b7fcef0599a3e514cea7df3a87 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 6 May 2013 18:53:45 -0700 Subject: core::rt: 0 is a valid TLS key --- src/rt/rust_builtin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/rt') diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 90328928122..39a6f5bfd1b 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -830,9 +830,9 @@ rust_get_rt_env() { } #ifndef _WIN32 -pthread_key_t sched_key; +pthread_key_t sched_key = -1; #else -DWORD sched_key; +DWORD sched_key = -1; #endif extern "C" void* -- cgit 1.4.1-3-g733a5 From 204e3d82ccf5015e39f847aafea148d5180ab951 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 11 May 2013 18:59:28 -0700 Subject: core::rt: Register stacks with valgrind. #6428 --- src/libcore/rt/io/net/tcp.rs | 2 +- src/libcore/rt/stack.rs | 39 ++++++++++++++++++++++++++++++++++----- src/rt/rust_stack.cpp | 11 +++++++++++ src/rt/rustrt.def.in | 2 ++ 4 files changed, 48 insertions(+), 6 deletions(-) (limited to 'src/rt') diff --git a/src/libcore/rt/io/net/tcp.rs b/src/libcore/rt/io/net/tcp.rs index 90f99f8df8b..b4c021ed28f 100644 --- a/src/libcore/rt/io/net/tcp.rs +++ b/src/libcore/rt/io/net/tcp.rs @@ -122,7 +122,7 @@ mod test { use rt::io::net::ip::Ipv4; use rt::io::*; - #[test] + #[test] #[ignore] fn bind_error() { do run_in_newsched_task { let mut called = false; diff --git a/src/libcore/rt/stack.rs b/src/libcore/rt/stack.rs index 9eca3bda047..068bc834ce6 100644 --- a/src/libcore/rt/stack.rs +++ b/src/libcore/rt/stack.rs @@ -9,21 +9,36 @@ // except according to those terms. use vec; +use ops::Drop; +use libc::{c_uint, uintptr_t}; pub struct StackSegment { - buf: ~[u8] + buf: ~[u8], + valgrind_id: c_uint } pub impl StackSegment { fn new(size: uint) -> StackSegment { - // Crate a block of uninitialized values - let mut stack = vec::with_capacity(size); unsafe { + // Crate a block of uninitialized values + let mut stack = vec::with_capacity(size); vec::raw::set_len(&mut stack, size); + + let mut stk = StackSegment { + buf: stack, + valgrind_id: 0 + }; + + // XXX: Using the FFI to call a C macro. Slow + stk.valgrind_id = rust_valgrind_stack_register(stk.start(), stk.end()); + return stk; } + } - StackSegment { - buf: stack + /// Point to the low end of the allocated stack + fn start(&self) -> *uint { + unsafe { + vec::raw::to_ptr(self.buf) as *uint } } @@ -35,6 +50,15 @@ pub impl StackSegment { } } +impl Drop for StackSegment { + fn finalize(&self) { + unsafe { + // XXX: Using the FFI to call a C macro. Slow + rust_valgrind_stack_deregister(self.valgrind_id); + } + } +} + pub struct StackPool(()); impl StackPool { @@ -47,3 +71,8 @@ impl StackPool { fn give_segment(&self, _stack: StackSegment) { } } + +extern { + fn rust_valgrind_stack_register(start: *uintptr_t, end: *uintptr_t) -> c_uint; + fn rust_valgrind_stack_deregister(id: c_uint); +} \ No newline at end of file diff --git a/src/rt/rust_stack.cpp b/src/rt/rust_stack.cpp index f07690a955e..a609ac57324 100644 --- a/src/rt/rust_stack.cpp +++ b/src/rt/rust_stack.cpp @@ -92,3 +92,14 @@ destroy_exchange_stack(rust_exchange_alloc *exchange, stk_seg *stk) { deregister_valgrind_stack(stk); exchange->free(stk); } + + +extern "C" CDECL unsigned int +rust_valgrind_stack_register(void *start, void *end) { + return VALGRIND_STACK_REGISTER(start, end); +} + +extern "C" CDECL void +rust_valgrind_stack_deregister(unsigned int id) { + VALGRIND_STACK_DEREGISTER(id); +} diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 6be41251f1b..75a5a069605 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -234,3 +234,5 @@ rust_try rust_begin_unwind rust_take_task_borrow_list rust_set_task_borrow_list +rust_valgrind_stack_register +rust_valgrind_stack_deregister \ No newline at end of file -- cgit 1.4.1-3-g733a5 From bfd9aa9755149725e39d8024d693ed76f92a30df Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 7 May 2013 18:13:15 -0700 Subject: core:rt: A few micro-opts --- src/libcore/rt/context.rs | 1 + src/libcore/rt/global_heap.rs | 14 +++++++++----- src/libcore/rt/local_sched.rs | 1 + src/libcore/rt/thread_local_storage.rs | 3 +++ src/rt/rust_exchange_alloc.cpp | 16 ++++++---------- src/rt/rustrt.def.in | 2 +- 6 files changed, 21 insertions(+), 16 deletions(-) (limited to 'src/rt') diff --git a/src/libcore/rt/context.rs b/src/libcore/rt/context.rs index 9c1612884f0..2add314fd11 100644 --- a/src/libcore/rt/context.rs +++ b/src/libcore/rt/context.rs @@ -84,6 +84,7 @@ pub impl Context { } extern { + #[rust_stack] fn swap_registers(out_regs: *mut Registers, in_regs: *Registers); } diff --git a/src/libcore/rt/global_heap.rs b/src/libcore/rt/global_heap.rs index 3b35c2fb804..ce7ff87b445 100644 --- a/src/libcore/rt/global_heap.rs +++ b/src/libcore/rt/global_heap.rs @@ -9,7 +9,7 @@ // except according to those terms. use sys::{TypeDesc, size_of}; -use libc::{c_void, size_t}; +use libc::{c_void, size_t, uintptr_t}; use c_malloc = libc::malloc; use c_free = libc::free; use managed::raw::{BoxHeaderRepr, BoxRepr}; @@ -34,7 +34,7 @@ pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void { box.header.prev = null(); box.header.next = null(); - let exchange_count = &mut *rust_get_exchange_count_ptr(); + let exchange_count = &mut *exchange_count_ptr(); atomic_xadd(exchange_count, 1); return transmute(box); @@ -52,7 +52,7 @@ pub unsafe fn malloc_raw(size: uint) -> *c_void { } pub unsafe fn free(ptr: *c_void) { - let exchange_count = &mut *rust_get_exchange_count_ptr(); + let exchange_count = &mut *exchange_count_ptr(); atomic_xsub(exchange_count, 1); assert!(ptr.is_not_null()); @@ -77,7 +77,11 @@ fn align_to(size: uint, align: uint) -> uint { (size + align - 1) & !(align - 1) } +fn exchange_count_ptr() -> *mut int { + // XXX: Need mutable globals + unsafe { transmute(&rust_exchange_count) } +} + extern { - #[rust_stack] - fn rust_get_exchange_count_ptr() -> *mut int; + static rust_exchange_count: uintptr_t; } diff --git a/src/libcore/rt/local_sched.rs b/src/libcore/rt/local_sched.rs index eb35eb7881d..1ef1fd33a83 100644 --- a/src/libcore/rt/local_sched.rs +++ b/src/libcore/rt/local_sched.rs @@ -126,6 +126,7 @@ fn maybe_tls_key() -> Option { } extern { + #[fast_ffi] fn rust_get_sched_tls_key() -> *mut c_void; } diff --git a/src/libcore/rt/thread_local_storage.rs b/src/libcore/rt/thread_local_storage.rs index 366996fb935..6a08c0f59b1 100644 --- a/src/libcore/rt/thread_local_storage.rs +++ b/src/libcore/rt/thread_local_storage.rs @@ -46,8 +46,11 @@ type pthread_key_t = ::libc::c_uint; #[cfg(unix)] extern { + #[fast_ffi] fn pthread_key_create(key: *mut pthread_key_t, dtor: *u8) -> c_int; + #[fast_ffi] fn pthread_setspecific(key: pthread_key_t, value: *mut c_void) -> c_int; + #[fast_ffi] fn pthread_getspecific(key: pthread_key_t) -> *mut c_void; } diff --git a/src/rt/rust_exchange_alloc.cpp b/src/rt/rust_exchange_alloc.cpp index 5958c68f3e7..89257dc9f6e 100644 --- a/src/rt/rust_exchange_alloc.cpp +++ b/src/rt/rust_exchange_alloc.cpp @@ -15,14 +15,15 @@ #include #include -uintptr_t exchange_count = 0; +extern uintptr_t rust_exchange_count; +uintptr_t rust_exchange_count = 0; void * rust_exchange_alloc::malloc(size_t size) { void *value = ::malloc(size); assert(value); - sync::increment(exchange_count); + sync::increment(rust_exchange_count); return value; } @@ -36,20 +37,15 @@ rust_exchange_alloc::realloc(void *ptr, size_t size) { void rust_exchange_alloc::free(void *ptr) { - sync::decrement(exchange_count); + sync::decrement(rust_exchange_count); ::free(ptr); } -extern "C" uintptr_t * -rust_get_exchange_count_ptr() { - return &exchange_count; -} - void rust_check_exchange_count_on_exit() { - if (exchange_count != 0) { + if (rust_exchange_count != 0) { printf("exchange heap not empty on exit\n"); - printf("%d dangling allocations\n", (int)exchange_count); + printf("%d dangling allocations\n", (int)rust_exchange_count); abort(); } } diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 75a5a069605..a62d7991d49 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -195,7 +195,7 @@ rust_register_exit_function rust_get_global_data_ptr rust_inc_kernel_live_count rust_dec_kernel_live_count -rust_get_exchange_count_ptr +rust_exchange_count rust_get_sched_tls_key swap_registers rust_readdir -- cgit 1.4.1-3-g733a5 From f6401bad24d2fb1e1f959595c2f57cb4964e7082 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 8 May 2013 15:26:07 -0700 Subject: core: Use a global lock instead of runtime lock for os::getenv, etc. #4726 --- src/libcore/os.rs | 26 ++++++++++++++------------ src/libuv | 2 +- src/rt/rust_env.cpp | 16 ++++++++++++++++ src/rt/rustrt.def.in | 5 ++++- 4 files changed, 35 insertions(+), 14 deletions(-) (limited to 'src/rt') diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 93319efa3b7..a198b495127 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -147,23 +147,25 @@ pub mod win32 { /* Accessing environment variables is not generally threadsafe. -This uses a per-runtime lock to serialize access. -FIXME #4726: It would probably be appropriate to make this a real global +Serialize access through a global lock. */ fn with_env_lock(f: &fn() -> T) -> T { - use unstable::global::global_data_clone_create; - use unstable::sync::{Exclusive, exclusive}; - - struct SharedValue(()); - type ValueMutex = Exclusive; - fn key(_: ValueMutex) { } + use unstable::finally::Finally; unsafe { - let lock: ValueMutex = global_data_clone_create(key, || { - ~exclusive(SharedValue(())) - }); + return do (|| { + rust_take_env_lock(); + f() + }).finally { + rust_drop_env_lock(); + }; + } - lock.with_imm(|_| f() ) + extern { + #[fast_ffi] + fn rust_take_env_lock(); + #[fast_ffi] + fn rust_drop_env_lock(); } } diff --git a/src/libuv b/src/libuv index 97ac7c087a0..218ab86721e 160000 --- a/src/libuv +++ b/src/libuv @@ -1 +1 @@ -Subproject commit 97ac7c087a0caf6b0f611b80e14f7fe3cb18bb27 +Subproject commit 218ab86721eefd7b7e97fa6d9f95a80a1fa8686c diff --git a/src/rt/rust_env.cpp b/src/rt/rust_env.cpp index 360d6114928..ed38be3550f 100644 --- a/src/rt/rust_env.cpp +++ b/src/rt/rust_env.cpp @@ -13,6 +13,7 @@ // that might come from the environment is loaded here, once, during // init. +#include "sync/lock_and_signal.h" #include "rust_env.h" // The environment variables that the runtime knows about @@ -26,6 +27,18 @@ #define RUST_DEBUG_MEM "RUST_DEBUG_MEM" #define RUST_DEBUG_BORROW "RUST_DEBUG_BORROW" +static lock_and_signal env_lock; + +extern "C" CDECL void +rust_take_env_lock() { + env_lock.lock(); +} + +extern "C" CDECL void +rust_drop_env_lock() { + env_lock.unlock(); +} + #if defined(__WIN32__) static int get_num_cpus() { @@ -119,6 +132,8 @@ copyenv(const char* name) { rust_env* load_env(int argc, char **argv) { + scoped_lock with(env_lock); + rust_env *env = (rust_env*)malloc(sizeof(rust_env)); env->num_sched_threads = (size_t)get_num_threads(); @@ -141,3 +156,4 @@ free_env(rust_env *env) { free(env->rust_seed); free(env); } + diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index a62d7991d49..958b31eb342 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -235,4 +235,7 @@ rust_begin_unwind rust_take_task_borrow_list rust_set_task_borrow_list rust_valgrind_stack_register -rust_valgrind_stack_deregister \ No newline at end of file +rust_valgrind_stack_deregister +rust_take_env_lock +rust_drop_env_lock + -- cgit 1.4.1-3-g733a5 From 0a54bad3d1d306845b04f146c2c31d4a70e9ede3 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 8 May 2013 16:53:40 -0700 Subject: core::rt: Initialize logging --- src/libcore/rt/logging.rs | 32 +++++++++++++++++++++++++++++++- src/libcore/rt/mod.rs | 11 +++++++++-- src/libcore/unstable/lang.rs | 2 +- src/rt/rust_log.cpp | 4 ++++ src/rt/rustrt.def.in | 2 +- 5 files changed, 46 insertions(+), 5 deletions(-) (limited to 'src/rt') diff --git a/src/libcore/rt/logging.rs b/src/libcore/rt/logging.rs index 4ed09fd829f..a0d05397689 100644 --- a/src/libcore/rt/logging.rs +++ b/src/libcore/rt/logging.rs @@ -35,4 +35,34 @@ impl Logger for StdErrLogger { dbg.write_str("\n"); dbg.flush(); } -} \ No newline at end of file +} + +/// Configure logging by traversing the crate map and setting the +/// per-module global logging flags based on the logging spec +pub fn init(crate_map: *u8) { + use os; + use str; + use ptr; + use option::{Some, None}; + use libc::c_char; + + let log_spec = os::getenv("RUST_LOG"); + match log_spec { + Some(spec) => { + do str::as_c_str(spec) |s| { + unsafe { + rust_update_log_settings(crate_map, s); + } + } + } + None => { + unsafe { + rust_update_log_settings(crate_map, ptr::null()); + } + } + } + + extern { + fn rust_update_log_settings(crate_map: *u8, settings: *c_char); + } +} diff --git a/src/libcore/rt/mod.rs b/src/libcore/rt/mod.rs index 5dee9a77731..cebc87f8c23 100644 --- a/src/libcore/rt/mod.rs +++ b/src/libcore/rt/mod.rs @@ -62,7 +62,6 @@ Several modules in `core` are clients of `rt`: #[doc(hidden)]; -use libc::c_char; use ptr::Ptr; /// The global (exchange) heap. @@ -138,11 +137,13 @@ pub mod tube; /// # Return value /// /// The return value is used as the process return code. 0 on success, 101 on error. -pub fn start(_argc: int, _argv: **c_char, _crate_map: *u8, main: ~fn()) -> int { +pub fn start(_argc: int, _argv: **u8, crate_map: *u8, main: ~fn()) -> int { use self::sched::{Scheduler, Task}; use self::uv::uvio::UvEventLoop; + init(crate_map); + let loop_ = ~UvEventLoop::new(); let mut sched = ~Scheduler::new(loop_); let main_task = ~Task::new(&mut sched.stack_pool, main); @@ -153,6 +154,12 @@ pub fn start(_argc: int, _argv: **c_char, _crate_map: *u8, main: ~fn()) -> int { return 0; } +/// One-time runtime initialization. Currently all this does is set up logging +/// based on the RUST_LOG environment variable. +pub fn init(crate_map: *u8) { + logging::init(crate_map); +} + /// Possible contexts in which Rust code may be executing. /// Different runtime services are available depending on context. /// Mostly used for determining if we're using the new scheduler diff --git a/src/libcore/unstable/lang.rs b/src/libcore/unstable/lang.rs index 071d21ae8a8..1249392484d 100644 --- a/src/libcore/unstable/lang.rs +++ b/src/libcore/unstable/lang.rs @@ -435,7 +435,7 @@ pub fn start(main: *u8, argc: int, argv: **c_char, 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, crate_map) { + return do rt::start(argc, argv as **u8, crate_map) { unsafe { // `main` is an `fn() -> ()` that doesn't take an environment // XXX: Could also call this as an `extern "Rust" fn` once they work diff --git a/src/rt/rust_log.cpp b/src/rt/rust_log.cpp index c2b58c9fda7..df24f569495 100644 --- a/src/rt/rust_log.cpp +++ b/src/rt/rust_log.cpp @@ -324,6 +324,10 @@ void update_log_settings(void* crate_map, char* settings) { free(buffer); } +extern "C" CDECL void +rust_update_log_settings(void* crate_map, char* settings) { + update_log_settings(crate_map, settings); +} // // Local Variables: diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 958b31eb342..f1ddb17c499 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -238,4 +238,4 @@ rust_valgrind_stack_register rust_valgrind_stack_deregister rust_take_env_lock rust_drop_env_lock - +rust_update_log_settings -- cgit 1.4.1-3-g733a5 From 4724966b0656761da94e24e73b028cd0d3420a7e Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 10 May 2013 17:07:41 -0700 Subject: core::rt: Add uv timer bindings --- src/libcore/rt/local_sched.rs | 5 +- src/libcore/rt/uv/mod.rs | 9 +- src/libcore/rt/uv/timer.rs | 186 ++++++++++++++++++++++++++++++++++++++++++ src/libcore/rt/uv/uvll.rs | 10 +-- src/libstd/uv_ll.rs | 8 +- src/rt/rust_uv.cpp | 2 +- 6 files changed, 207 insertions(+), 13 deletions(-) create mode 100644 src/libcore/rt/uv/timer.rs (limited to 'src/rt') diff --git a/src/libcore/rt/local_sched.rs b/src/libcore/rt/local_sched.rs index 1ef1fd33a83..ffc19c5b5e4 100644 --- a/src/libcore/rt/local_sched.rs +++ b/src/libcore/rt/local_sched.rs @@ -97,7 +97,10 @@ pub unsafe fn unsafe_borrow_io() -> *mut IoFactoryObject { } fn tls_key() -> tls::Key { - maybe_tls_key().get() + match maybe_tls_key() { + Some(key) => key, + None => abort!("runtime tls key not initialized") + } } fn maybe_tls_key() -> Option { diff --git a/src/libcore/rt/uv/mod.rs b/src/libcore/rt/uv/mod.rs index 871fd2a9042..ee3c5ceffd2 100644 --- a/src/libcore/rt/uv/mod.rs +++ b/src/libcore/rt/uv/mod.rs @@ -59,6 +59,7 @@ use rt::io::IoError; pub use self::file::FsRequest; pub use self::net::{StreamWatcher, TcpWatcher}; pub use self::idle::IdleWatcher; +pub use self::timer::TimerWatcher; /// The implementation of `rtio` for libuv pub mod uvio; @@ -69,6 +70,7 @@ pub mod uvll; pub mod file; pub mod net; pub mod idle; +pub mod timer; /// XXX: Loop(*handle) is buggy with destructors. Normal structs /// with dtors may not be destructured, but tuple structs can, @@ -125,6 +127,7 @@ pub type NullCallback = ~fn(); pub type IdleCallback = ~fn(IdleWatcher, Option); pub type ConnectionCallback = ~fn(StreamWatcher, Option); pub type FsCallback = ~fn(FsRequest, Option); +pub type TimerCallback = ~fn(TimerWatcher, Option); /// Callbacks used by StreamWatchers, set as custom data on the foreign handle @@ -134,7 +137,8 @@ struct WatcherData { connect_cb: Option, close_cb: Option, alloc_cb: Option, - idle_cb: Option + idle_cb: Option, + timer_cb: Option } pub trait WatcherInterop { @@ -162,7 +166,8 @@ impl> WatcherInterop for W { connect_cb: None, close_cb: None, alloc_cb: None, - idle_cb: None + idle_cb: None, + timer_cb: None }; let data = transmute::<~WatcherData, *c_void>(data); uvll::set_data_for_uv_handle(self.native_handle(), data); diff --git a/src/libcore/rt/uv/timer.rs b/src/libcore/rt/uv/timer.rs new file mode 100644 index 00000000000..1045a77da12 --- /dev/null +++ b/src/libcore/rt/uv/timer.rs @@ -0,0 +1,186 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use libc::{c_void, c_int}; +use option::Some; +use rt::uv::uvll; +use rt::uv::{Watcher, Loop, NativeHandle, TimerCallback, NullCallback}; +use rt::uv::status_to_maybe_uv_error; + +pub struct TimerWatcher(*uvll::uv_timer_t); +impl Watcher for TimerWatcher { } + +impl TimerWatcher { + pub fn new(loop_: &mut Loop) -> TimerWatcher { + unsafe { + let handle = uvll::malloc_handle(uvll::UV_TIMER); + assert!(handle.is_not_null()); + assert!(0 == uvll::timer_init(loop_.native_handle(), handle)); + let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle); + watcher.install_watcher_data(); + return watcher; + } + } + + pub fn start(&mut self, timeout: u64, repeat: u64, cb: TimerCallback) { + { + let data = self.get_watcher_data(); + data.timer_cb = Some(cb); + } + + unsafe { + uvll::timer_start(self.native_handle(), timer_cb, timeout, repeat); + } + + extern fn timer_cb(handle: *uvll::uv_timer_t, status: c_int) { + let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle); + let data = watcher.get_watcher_data(); + let cb = data.timer_cb.get_ref(); + let status = status_to_maybe_uv_error(handle, status); + (*cb)(watcher, status); + } + } + + pub fn stop(&mut self) { + unsafe { + uvll::timer_stop(self.native_handle()); + } + } + + pub fn close(self, cb: NullCallback) { + let mut watcher = self; + { + let data = watcher.get_watcher_data(); + assert!(data.close_cb.is_none()); + data.close_cb = Some(cb); + } + + unsafe { + uvll::close(watcher.native_handle(), close_cb); + } + + extern fn close_cb(handle: *uvll::uv_timer_t) { + let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle); + { + let mut data = watcher.get_watcher_data(); + data.close_cb.swap_unwrap()(); + } + watcher.drop_watcher_data(); + unsafe { + uvll::free_handle(handle as *c_void); + } + } + } +} + +impl NativeHandle<*uvll::uv_timer_t> for TimerWatcher { + fn from_native_handle(handle: *uvll::uv_timer_t) -> TimerWatcher { + TimerWatcher(handle) + } + fn native_handle(&self) -> *uvll::uv_idle_t { + match self { &TimerWatcher(ptr) => ptr } + } +} + +#[cfg(test)] +mod test { + use super::*; + use rt::uv::Loop; + use unstable::run_in_bare_thread; + + #[test] + fn smoke_test() { + do run_in_bare_thread { + let mut count = 0; + let count_ptr: *mut int = &mut count; + let mut loop_ = Loop::new(); + let mut timer = TimerWatcher::new(&mut loop_); + do timer.start(10, 0) |timer, status| { + assert!(status.is_none()); + unsafe { *count_ptr += 1 }; + timer.close(||()); + } + loop_.run(); + loop_.close(); + assert!(count == 1); + } + } + + #[test] + fn start_twice() { + do run_in_bare_thread { + let mut count = 0; + let count_ptr: *mut int = &mut count; + let mut loop_ = Loop::new(); + let mut timer = TimerWatcher::new(&mut loop_); + do timer.start(10, 0) |timer, status| { + let mut timer = timer; + assert!(status.is_none()); + unsafe { *count_ptr += 1 }; + do timer.start(10, 0) |timer, status| { + let mut timer = timer; + assert!(status.is_none()); + unsafe { *count_ptr += 1 }; + timer.close(||()); + } + } + loop_.run(); + loop_.close(); + assert!(count == 2); + } + } + + #[test] + fn repeat_stop() { + do run_in_bare_thread { + let mut count = 0; + let count_ptr: *mut int = &mut count; + let mut loop_ = Loop::new(); + let mut timer = TimerWatcher::new(&mut loop_); + do timer.start(10, 20) |timer, status| { + assert!(status.is_none()); + unsafe { + *count_ptr += 1; + + if *count_ptr == 10 { + + // Stop the timer and do something else + let mut timer = timer; + timer.stop(); + // Freeze timer so it can be captured + let timer = timer; + + let mut loop_ = timer.event_loop(); + let mut timer2 = TimerWatcher::new(&mut loop_); + do timer2.start(10, 0) |timer2, status| { + + unsafe { *count_ptr += 1; } + + let mut timer2 = timer2; + timer2.close(||()); + + // Restart the original timer + let mut timer = timer; + do timer.start(10, 0) |timer, status| { + unsafe { *count_ptr += 1; } + let mut timer = timer; + timer.close(||()); + } + } + } + }; + } + loop_.run(); + loop_.close(); + assert!(count == 12); + } + } + +} diff --git a/src/libcore/rt/uv/uvll.rs b/src/libcore/rt/uv/uvll.rs index 76abf2a195d..94e6b82ab8f 100644 --- a/src/libcore/rt/uv/uvll.rs +++ b/src/libcore/rt/uv/uvll.rs @@ -268,9 +268,9 @@ pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t { pub unsafe fn timer_init(loop_ptr: *c_void, timer_ptr: *uv_timer_t) -> c_int { return rust_uv_timer_init(loop_ptr, timer_ptr); } -pub unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: uint, - repeat: uint) -> c_int { - return rust_uv_timer_start(timer_ptr, cb, timeout as c_uint, repeat as c_uint); +pub unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: u64, + repeat: u64) -> c_int { + return rust_uv_timer_start(timer_ptr, cb, timeout, repeat); } pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> c_int { return rust_uv_timer_stop(timer_ptr); @@ -431,8 +431,8 @@ extern { timer_handle: *uv_timer_t) -> c_int; fn rust_uv_timer_start(timer_handle: *uv_timer_t, cb: *u8, - timeout: c_uint, - repeat: c_uint) -> c_int; + timeout: libc::uint64_t, + repeat: libc::uint64_t) -> c_int; fn rust_uv_timer_stop(handle: *uv_timer_t) -> c_int; fn rust_uv_malloc_buf_base_of(sug_size: size_t) -> *u8; diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs index a14c048b8de..96ceb1002d8 100644 --- a/src/libstd/uv_ll.rs +++ b/src/libstd/uv_ll.rs @@ -819,8 +819,8 @@ extern { unsafe fn rust_uv_timer_start( timer_handle: *uv_timer_t, cb: *u8, - timeout: libc::c_uint, - repeat: libc::c_uint) -> libc::c_int; + timeout: libc::uint64_t, + repeat: libc::uint64_t) -> libc::c_int; unsafe fn rust_uv_timer_stop(handle: *uv_timer_t) -> libc::c_int; unsafe fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void, @@ -1084,8 +1084,8 @@ pub unsafe fn timer_init(loop_ptr: *libc::c_void, } pub unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: uint, repeat: uint) -> libc::c_int { - return rust_uv_timer_start(timer_ptr, cb, timeout as libc::c_uint, - repeat as libc::c_uint); + return rust_uv_timer_start(timer_ptr, cb, timeout as libc::uint64_t, + repeat as libc::uint64_t); } pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> libc::c_int { return rust_uv_timer_stop(timer_ptr); diff --git a/src/rt/rust_uv.cpp b/src/rt/rust_uv.cpp index 8cf2bd4b4ac..fefcbbcacf7 100644 --- a/src/rt/rust_uv.cpp +++ b/src/rt/rust_uv.cpp @@ -229,7 +229,7 @@ rust_uv_timer_init(uv_loop_t* loop, uv_timer_t* timer) { extern "C" int rust_uv_timer_start(uv_timer_t* the_timer, uv_timer_cb cb, - uint32_t timeout, uint32_t repeat) { + int64_t timeout, int64_t repeat) { return uv_timer_start(the_timer, cb, timeout, repeat); } -- cgit 1.4.1-3-g733a5 From 56c0b188b66f71f55e2d577ca4a23830a31433e6 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 11 May 2013 19:46:43 -0700 Subject: rt: Rename sched_key to rt_key It is more general-purpose than holding scheduler pointers --- src/libcore/rt/local_sched.rs | 4 ++-- src/rt/rust_builtin.cpp | 14 +++++++------- src/rt/rustrt.def.in | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/rt') diff --git a/src/libcore/rt/local_sched.rs b/src/libcore/rt/local_sched.rs index ffc19c5b5e4..895354d2218 100644 --- a/src/libcore/rt/local_sched.rs +++ b/src/libcore/rt/local_sched.rs @@ -105,7 +105,7 @@ fn tls_key() -> tls::Key { fn maybe_tls_key() -> Option { unsafe { - let key: *mut c_void = rust_get_sched_tls_key(); + let key: *mut c_void = rust_get_rt_tls_key(); let key: &mut tls::Key = cast::transmute(key); let key = *key; // Check that the key has been initialized. @@ -130,7 +130,7 @@ fn maybe_tls_key() -> Option { extern { #[fast_ffi] - fn rust_get_sched_tls_key() -> *mut c_void; + fn rust_get_rt_tls_key() -> *mut c_void; } #[test] diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 39a6f5bfd1b..1a64066b5a9 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -830,14 +830,14 @@ rust_get_rt_env() { } #ifndef _WIN32 -pthread_key_t sched_key = -1; +pthread_key_t rt_key = -1; #else -DWORD sched_key = -1; +DWORD rt_key = -1; #endif extern "C" void* -rust_get_sched_tls_key() { - return &sched_key; +rust_get_rt_tls_key() { + return &rt_key; } // Initialize the global state required by the new scheduler @@ -852,10 +852,10 @@ rust_initialize_global_state() { if (!initialized) { #ifndef _WIN32 - assert(!pthread_key_create(&sched_key, NULL)); + assert(!pthread_key_create(&rt_key, NULL)); #else - sched_key = TlsAlloc(); - assert(sched_key != TLS_OUT_OF_INDEXES); + rt_key = TlsAlloc(); + assert(rt_key != TLS_OUT_OF_INDEXES); #endif initialized = true; diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index f1ddb17c499..cdc282440b8 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -196,7 +196,7 @@ rust_get_global_data_ptr rust_inc_kernel_live_count rust_dec_kernel_live_count rust_exchange_count -rust_get_sched_tls_key +rust_get_rt_tls_key swap_registers rust_readdir rust_opendir -- cgit 1.4.1-3-g733a5