mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 11:48:30 +00:00
Runtime removal: refactor timer
This patch continues runtime removal by moving out timer-related code into `sys`. Because this eliminates APIs in `libnative` and `librustrt`, it is a: [breaking-change] This functionality is likely to be available publicly, in some form, from `std` in the future.
This commit is contained in:
parent
0f98e75b69
commit
b8f1193bb1
@ -29,19 +29,6 @@ use std::os;
|
|||||||
use std::rt::rtio::{mod, IoResult, IoError};
|
use std::rt::rtio::{mod, IoResult, IoError};
|
||||||
use std::num;
|
use std::num;
|
||||||
|
|
||||||
#[cfg(any(target_os = "macos",
|
|
||||||
target_os = "ios",
|
|
||||||
target_os = "freebsd",
|
|
||||||
target_os = "dragonfly",
|
|
||||||
target_os = "android",
|
|
||||||
target_os = "linux"))]
|
|
||||||
#[path = "timer_unix.rs"]
|
|
||||||
pub mod timer;
|
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
#[path = "timer_windows.rs"]
|
|
||||||
pub mod timer;
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
#[path = "tty_windows.rs"]
|
#[path = "tty_windows.rs"]
|
||||||
mod tty;
|
mod tty;
|
||||||
@ -112,10 +99,6 @@ impl IoFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl rtio::IoFactory for IoFactory {
|
impl rtio::IoFactory for IoFactory {
|
||||||
// misc
|
|
||||||
fn timer_init(&mut self) -> IoResult<Box<rtio::RtioTimer + Send>> {
|
|
||||||
timer::Timer::new().map(|t| box t as Box<rtio::RtioTimer + Send>)
|
|
||||||
}
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn tty_open(&mut self, fd: c_int, _readable: bool)
|
fn tty_open(&mut self, fd: c_int, _readable: bool)
|
||||||
-> IoResult<Box<rtio::RtioTTY + Send>> {
|
-> IoResult<Box<rtio::RtioTTY + Send>> {
|
||||||
|
@ -21,10 +21,9 @@ and create receivers which will receive notifications after a period of time.
|
|||||||
|
|
||||||
use comm::{Receiver, Sender, channel};
|
use comm::{Receiver, Sender, channel};
|
||||||
use time::Duration;
|
use time::Duration;
|
||||||
use io::{IoResult, IoError};
|
use io::IoResult;
|
||||||
use kinds::Send;
|
use sys::timer::Callback;
|
||||||
use boxed::Box;
|
use sys::timer::Timer as TimerImp;
|
||||||
use rt::rtio::{IoFactory, LocalIo, RtioTimer, Callback};
|
|
||||||
|
|
||||||
/// A synchronous timer object
|
/// A synchronous timer object
|
||||||
///
|
///
|
||||||
@ -69,7 +68,7 @@ use rt::rtio::{IoFactory, LocalIo, RtioTimer, Callback};
|
|||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub struct Timer {
|
pub struct Timer {
|
||||||
obj: Box<RtioTimer + Send>,
|
inner: TimerImp,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TimerCallback { tx: Sender<()> }
|
struct TimerCallback { tx: Sender<()> }
|
||||||
@ -90,9 +89,7 @@ impl Timer {
|
|||||||
/// for a number of milliseconds, or to possibly create channels which will
|
/// for a number of milliseconds, or to possibly create channels which will
|
||||||
/// get notified after an amount of time has passed.
|
/// get notified after an amount of time has passed.
|
||||||
pub fn new() -> IoResult<Timer> {
|
pub fn new() -> IoResult<Timer> {
|
||||||
LocalIo::maybe_raise(|io| {
|
TimerImp::new().map(|t| Timer { inner: t })
|
||||||
io.timer_init().map(|t| Timer { obj: t })
|
|
||||||
}).map_err(IoError::from_rtio_error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Blocks the current task for the specified duration.
|
/// Blocks the current task for the specified duration.
|
||||||
@ -106,7 +103,7 @@ impl Timer {
|
|||||||
// Short-circuit the timer backend for 0 duration
|
// Short-circuit the timer backend for 0 duration
|
||||||
let ms = in_ms_u64(duration);
|
let ms = in_ms_u64(duration);
|
||||||
if ms == 0 { return }
|
if ms == 0 { return }
|
||||||
self.obj.sleep(ms);
|
self.inner.sleep(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a oneshot receiver which will have a notification sent when
|
/// Creates a oneshot receiver which will have a notification sent when
|
||||||
@ -152,7 +149,7 @@ impl Timer {
|
|||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
// Short-circuit the timer backend for 0 duration
|
// Short-circuit the timer backend for 0 duration
|
||||||
if in_ms_u64(duration) != 0 {
|
if in_ms_u64(duration) != 0 {
|
||||||
self.obj.oneshot(in_ms_u64(duration), box TimerCallback { tx: tx });
|
self.inner.oneshot(in_ms_u64(duration), box TimerCallback { tx: tx });
|
||||||
} else {
|
} else {
|
||||||
tx.send(());
|
tx.send(());
|
||||||
}
|
}
|
||||||
@ -213,7 +210,7 @@ impl Timer {
|
|||||||
// not clear what use a 0ms period is anyway...
|
// not clear what use a 0ms period is anyway...
|
||||||
let ms = if ms == 0 { 1 } else { ms };
|
let ms = if ms == 0 { 1 } else { ms };
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
self.obj.period(ms, box TimerCallback { tx: tx });
|
self.inner.period(ms, box TimerCallback { tx: tx });
|
||||||
return rx
|
return rx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ pub mod udp;
|
|||||||
pub mod pipe;
|
pub mod pipe;
|
||||||
pub mod helper_signal;
|
pub mod helper_signal;
|
||||||
pub mod process;
|
pub mod process;
|
||||||
|
pub mod timer;
|
||||||
|
|
||||||
pub mod addrinfo {
|
pub mod addrinfo {
|
||||||
pub use sys_common::net::get_host_addresses;
|
pub use sys_common::net::get_host_addresses;
|
||||||
|
@ -47,27 +47,30 @@
|
|||||||
//! Note that all time units in this file are in *milliseconds*.
|
//! Note that all time units in this file are in *milliseconds*.
|
||||||
|
|
||||||
use libc;
|
use libc;
|
||||||
use std::mem;
|
use mem;
|
||||||
use std::os;
|
use os;
|
||||||
use std::ptr;
|
use ptr;
|
||||||
use std::rt::rtio;
|
use sync::atomic;
|
||||||
use std::rt::rtio::IoResult;
|
use comm;
|
||||||
use std::sync::atomic;
|
use sys::c;
|
||||||
use std::comm;
|
use sys::fs::FileDesc;
|
||||||
|
use sys_common::helper_thread::Helper;
|
||||||
use io::c;
|
use prelude::*;
|
||||||
use platform_imp::fs::FileDesc;
|
use io::IoResult;
|
||||||
use io::helper_thread::Helper;
|
|
||||||
|
|
||||||
helper_init!(static HELPER: Helper<Req>)
|
helper_init!(static HELPER: Helper<Req>)
|
||||||
|
|
||||||
|
pub trait Callback {
|
||||||
|
fn call(&mut self);
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Timer {
|
pub struct Timer {
|
||||||
id: uint,
|
id: uint,
|
||||||
inner: Option<Box<Inner>>,
|
inner: Option<Box<Inner>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Inner {
|
pub struct Inner {
|
||||||
cb: Option<Box<rtio::Callback + Send>>,
|
cb: Option<Box<Callback + Send>>,
|
||||||
interval: u64,
|
interval: u64,
|
||||||
repeat: bool,
|
repeat: bool,
|
||||||
target: u64,
|
target: u64,
|
||||||
@ -190,11 +193,11 @@ fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) {
|
|||||||
|
|
||||||
// drain the file descriptor
|
// drain the file descriptor
|
||||||
let mut buf = [0];
|
let mut buf = [0];
|
||||||
assert_eq!(fd.inner_read(buf).ok().unwrap(), 1);
|
assert_eq!(fd.read(buf).ok().unwrap(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
-1 if os::errno() == libc::EINTR as int => {}
|
-1 if os::errno() == libc::EINTR as uint => {}
|
||||||
n => panic!("helper thread panicked in select() with error: {} ({})",
|
n => panic!("helper thread failed in select() with error: {} ({})",
|
||||||
n, os::last_os_error())
|
n, os::last_os_error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,7 +223,11 @@ impl Timer {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sleep(ms: u64) {
|
pub fn sleep(&mut self, ms: u64) {
|
||||||
|
let mut inner = self.inner();
|
||||||
|
inner.cb = None; // cancel any previous request
|
||||||
|
self.inner = Some(inner);
|
||||||
|
|
||||||
let mut to_sleep = libc::timespec {
|
let mut to_sleep = libc::timespec {
|
||||||
tv_sec: (ms / 1000) as libc::time_t,
|
tv_sec: (ms / 1000) as libc::time_t,
|
||||||
tv_nsec: ((ms % 1000) * 1000000) as libc::c_long,
|
tv_nsec: ((ms % 1000) * 1000000) as libc::c_long,
|
||||||
@ -232,6 +239,30 @@ impl Timer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn oneshot(&mut self, msecs: u64, cb: Box<Callback + Send>) {
|
||||||
|
let now = now();
|
||||||
|
let mut inner = self.inner();
|
||||||
|
|
||||||
|
inner.repeat = false;
|
||||||
|
inner.cb = Some(cb);
|
||||||
|
inner.interval = msecs;
|
||||||
|
inner.target = now + msecs;
|
||||||
|
|
||||||
|
HELPER.send(NewTimer(inner));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn period(&mut self, msecs: u64, cb: Box<Callback + Send>) {
|
||||||
|
let now = now();
|
||||||
|
let mut inner = self.inner();
|
||||||
|
|
||||||
|
inner.repeat = true;
|
||||||
|
inner.cb = Some(cb);
|
||||||
|
inner.interval = msecs;
|
||||||
|
inner.target = now + msecs;
|
||||||
|
|
||||||
|
HELPER.send(NewTimer(inner));
|
||||||
|
}
|
||||||
|
|
||||||
fn inner(&mut self) -> Box<Inner> {
|
fn inner(&mut self) -> Box<Inner> {
|
||||||
match self.inner.take() {
|
match self.inner.take() {
|
||||||
Some(i) => i,
|
Some(i) => i,
|
||||||
@ -244,40 +275,6 @@ impl Timer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl rtio::RtioTimer for Timer {
|
|
||||||
fn sleep(&mut self, msecs: u64) {
|
|
||||||
let mut inner = self.inner();
|
|
||||||
inner.cb = None; // cancel any previous request
|
|
||||||
self.inner = Some(inner);
|
|
||||||
|
|
||||||
Timer::sleep(msecs);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn oneshot(&mut self, msecs: u64, cb: Box<rtio::Callback + Send>) {
|
|
||||||
let now = now();
|
|
||||||
let mut inner = self.inner();
|
|
||||||
|
|
||||||
inner.repeat = false;
|
|
||||||
inner.cb = Some(cb);
|
|
||||||
inner.interval = msecs;
|
|
||||||
inner.target = now + msecs;
|
|
||||||
|
|
||||||
HELPER.send(NewTimer(inner));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn period(&mut self, msecs: u64, cb: Box<rtio::Callback + Send>) {
|
|
||||||
let now = now();
|
|
||||||
let mut inner = self.inner();
|
|
||||||
|
|
||||||
inner.repeat = true;
|
|
||||||
inner.cb = Some(cb);
|
|
||||||
inner.interval = msecs;
|
|
||||||
inner.target = now + msecs;
|
|
||||||
|
|
||||||
HELPER.send(NewTimer(inner));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Timer {
|
impl Drop for Timer {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.inner = Some(self.inner());
|
self.inner = Some(self.inner());
|
@ -41,6 +41,7 @@ pub mod udp;
|
|||||||
pub mod pipe;
|
pub mod pipe;
|
||||||
pub mod helper_signal;
|
pub mod helper_signal;
|
||||||
pub mod process;
|
pub mod process;
|
||||||
|
pub mod timer;
|
||||||
|
|
||||||
pub mod addrinfo {
|
pub mod addrinfo {
|
||||||
pub use sys_common::net::get_host_addresses;
|
pub use sys_common::net::get_host_addresses;
|
||||||
|
@ -21,15 +21,21 @@
|
|||||||
//! the other two implementations of timers with nothing *that* new showing up.
|
//! the other two implementations of timers with nothing *that* new showing up.
|
||||||
|
|
||||||
use libc;
|
use libc;
|
||||||
use std::ptr;
|
use ptr;
|
||||||
use std::rt::rtio;
|
use comm;
|
||||||
use std::rt::rtio::{IoResult, Callback};
|
|
||||||
use std::comm;
|
|
||||||
|
|
||||||
use io::helper_thread::Helper;
|
use sys::c;
|
||||||
|
use sys::fs::FileDesc;
|
||||||
|
use sys_common::helper_thread::Helper;
|
||||||
|
use prelude::*;
|
||||||
|
use io::IoResult;
|
||||||
|
|
||||||
helper_init!(static HELPER: Helper<Req>)
|
helper_init!(static HELPER: Helper<Req>)
|
||||||
|
|
||||||
|
pub trait Callback {
|
||||||
|
fn call(&mut self);
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Timer {
|
pub struct Timer {
|
||||||
obj: libc::HANDLE,
|
obj: libc::HANDLE,
|
||||||
on_worker: bool,
|
on_worker: bool,
|
||||||
@ -116,12 +122,6 @@ impl Timer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sleep(ms: u64) {
|
|
||||||
use std::rt::rtio::RtioTimer;
|
|
||||||
let mut t = Timer::new().ok().expect("must allocate a timer!");
|
|
||||||
t.sleep(ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove(&mut self) {
|
fn remove(&mut self) {
|
||||||
if !self.on_worker { return }
|
if !self.on_worker { return }
|
||||||
|
|
||||||
@ -131,10 +131,8 @@ impl Timer {
|
|||||||
|
|
||||||
self.on_worker = false;
|
self.on_worker = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl rtio::RtioTimer for Timer {
|
pub fn sleep(&mut self, msecs: u64) {
|
||||||
fn sleep(&mut self, msecs: u64) {
|
|
||||||
self.remove();
|
self.remove();
|
||||||
|
|
||||||
// there are 10^6 nanoseconds in a millisecond, and the parameter is in
|
// there are 10^6 nanoseconds in a millisecond, and the parameter is in
|
||||||
@ -148,7 +146,7 @@ impl rtio::RtioTimer for Timer {
|
|||||||
let _ = unsafe { imp::WaitForSingleObject(self.obj, libc::INFINITE) };
|
let _ = unsafe { imp::WaitForSingleObject(self.obj, libc::INFINITE) };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn oneshot(&mut self, msecs: u64, cb: Box<Callback + Send>) {
|
pub fn oneshot(&mut self, msecs: u64, cb: Box<Callback + Send>) {
|
||||||
self.remove();
|
self.remove();
|
||||||
|
|
||||||
// see above for the calculation
|
// see above for the calculation
|
||||||
@ -162,7 +160,7 @@ impl rtio::RtioTimer for Timer {
|
|||||||
self.on_worker = true;
|
self.on_worker = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn period(&mut self, msecs: u64, cb: Box<Callback + Send>) {
|
pub fn period(&mut self, msecs: u64, cb: Box<Callback + Send>) {
|
||||||
self.remove();
|
self.remove();
|
||||||
|
|
||||||
// see above for the calculation
|
// see above for the calculation
|
Loading…
Reference in New Issue
Block a user