Skip to content

Commit ff34064

Browse files
committed
auto merge of #7916 : olsonjeffery/rust/newrt_timer, r=brson
My first bit of newsched IO work. Pretty simple and limited in scope. the RtioTimer trait only has a `sleep(msecs: u64)` method, for now. Taking requests on what else ought to be here. oh yeah: this resolves #6435
2 parents 73921f9 + 3169bb7 commit ff34064

File tree

4 files changed

+137
-0
lines changed

4 files changed

+137
-0
lines changed

src/libstd/rt/io/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ pub use self::stdio::print;
252252
pub use self::stdio::println;
253253

254254
pub use self::file::FileStream;
255+
pub use self::timer::Timer;
255256
pub use self::net::ip::IpAddr;
256257
pub use self::net::tcp::TcpListener;
257258
pub use self::net::tcp::TcpStream;
@@ -296,6 +297,9 @@ mod extensions;
296297
/// Non-I/O things needed by the I/O module
297298
mod support;
298299

300+
/// Basic Timer
301+
pub mod timer;
302+
299303
/// Thread-blocking implementations
300304
pub mod native {
301305
/// Posix file I/O

src/libstd/rt/io/timer.rs

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use option::{Option, Some, None};
12+
use result::{Ok, Err};
13+
use rt::io::{io_error};
14+
use rt::rtio::{IoFactory, IoFactoryObject,
15+
RtioTimer, RtioTimerObject};
16+
use rt::local::Local;
17+
18+
pub struct Timer(~RtioTimerObject);
19+
20+
impl Timer {
21+
fn new_on_rt(i: ~RtioTimerObject) -> Timer {
22+
Timer(i)
23+
}
24+
25+
pub fn new() -> Option<Timer> {
26+
let timer = unsafe {
27+
rtdebug!("Timer::init: borrowing io to init timer");
28+
let io = Local::unsafe_borrow::<IoFactoryObject>();
29+
rtdebug!("about to init timer");
30+
(*io).timer_init()
31+
};
32+
match timer {
33+
Ok(t) => Some(Timer::new_on_rt(t)),
34+
Err(ioerr) => {
35+
rtdebug!("Timer::init: failed to init: %?", ioerr);
36+
io_error::cond.raise(ioerr);
37+
None
38+
}
39+
}
40+
}
41+
}
42+
43+
impl RtioTimer for Timer {
44+
fn sleep(&self, msecs: u64) {
45+
(**self).sleep(msecs);
46+
}
47+
}
48+
49+
#[cfg(test)]
50+
mod test {
51+
use super::*;
52+
use rt::test::*;
53+
use option::{Some, None};
54+
#[test]
55+
fn test_io_timer_sleep_simple() {
56+
do run_in_newsched_task {
57+
let timer = Timer::new();
58+
match timer {
59+
Some(t) => t.sleep(1),
60+
None => assert!(false)
61+
}
62+
}
63+
}
64+
}

src/libstd/rt/rtio.rs

+6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub type IoFactoryObject = uvio::UvIoFactory;
2323
pub type RtioTcpStreamObject = uvio::UvTcpStream;
2424
pub type RtioTcpListenerObject = uvio::UvTcpListener;
2525
pub type RtioUdpSocketObject = uvio::UvUdpSocket;
26+
pub type RtioTimerObject = uvio::UvTimer;
2627

2728
pub trait EventLoop {
2829
fn run(&mut self);
@@ -46,6 +47,7 @@ pub trait IoFactory {
4647
fn tcp_connect(&mut self, addr: IpAddr) -> Result<~RtioTcpStreamObject, IoError>;
4748
fn tcp_bind(&mut self, addr: IpAddr) -> Result<~RtioTcpListenerObject, IoError>;
4849
fn udp_bind(&mut self, addr: IpAddr) -> Result<~RtioUdpSocketObject, IoError>;
50+
fn timer_init(&mut self) -> Result<~RtioTimerObject, IoError>;
4951
}
5052

5153
pub trait RtioTcpListener : RtioSocket {
@@ -84,3 +86,7 @@ pub trait RtioUdpSocket : RtioSocket {
8486
fn hear_broadcasts(&mut self);
8587
fn ignore_broadcasts(&mut self);
8688
}
89+
90+
pub trait RtioTimer {
91+
fn sleep(&self, msecs: u64);
92+
}

src/libstd/rt/uv/uvio.rs

+63
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,10 @@ impl IoFactory for UvIoFactory {
280280
}
281281
}
282282
}
283+
284+
fn timer_init(&mut self) -> Result<~RtioTimerObject, IoError> {
285+
Ok(~UvTimer(TimerWatcher::new(self.uv_loop())))
286+
}
283287
}
284288

285289
// FIXME #6090: Prefer newtype structs but Drop doesn't work
@@ -562,6 +566,48 @@ impl RtioUdpSocket for UvUdpSocket {
562566
fn ignore_broadcasts(&mut self) { fail!(); }
563567
}
564568

569+
pub struct UvTimer(timer::TimerWatcher);
570+
571+
impl UvTimer {
572+
fn new(w: timer::TimerWatcher) -> UvTimer {
573+
UvTimer(w)
574+
}
575+
}
576+
577+
impl Drop for UvTimer {
578+
fn drop(&self) {
579+
rtdebug!("closing UvTimer");
580+
let scheduler = Local::take::<Scheduler>();
581+
do scheduler.deschedule_running_task_and_then |_, task| {
582+
let task_cell = Cell::new(task);
583+
do self.close {
584+
let scheduler = Local::take::<Scheduler>();
585+
scheduler.resume_blocked_task_immediately(task_cell.take());
586+
}
587+
}
588+
}
589+
}
590+
591+
impl RtioTimer for UvTimer {
592+
fn sleep(&self, msecs: u64) {
593+
let scheduler = Local::take::<Scheduler>();
594+
assert!(scheduler.in_task_context());
595+
do scheduler.deschedule_running_task_and_then |sched, task| {
596+
rtdebug!("sleep: entered scheduler context");
597+
assert!(!sched.in_task_context());
598+
let task_cell = Cell::new(task);
599+
let mut watcher = **self;
600+
do watcher.start(msecs, 0) |_, status| {
601+
assert!(status.is_none());
602+
let scheduler = Local::take::<Scheduler>();
603+
scheduler.resume_blocked_task_immediately(task_cell.take());
604+
}
605+
}
606+
let mut w = **self;
607+
w.stop();
608+
}
609+
}
610+
565611
#[test]
566612
fn test_simple_io_no_connect() {
567613
do run_in_newsched_task {
@@ -832,3 +878,20 @@ fn test_udp_many_read() {
832878
}
833879
}
834880
}
881+
882+
fn test_timer_sleep_simple_impl() {
883+
unsafe {
884+
let io = Local::unsafe_borrow::<IoFactoryObject>();
885+
let timer = (*io).timer_init();
886+
match timer {
887+
Ok(t) => t.sleep(1),
888+
Err(_) => assert!(false)
889+
}
890+
}
891+
}
892+
#[test]
893+
fn test_timer_sleep_simple() {
894+
do run_in_newsched_task {
895+
test_timer_sleep_simple_impl();
896+
}
897+
}

0 commit comments

Comments
 (0)