Skip to content

Commit 4af518a

Browse files
committed
---
yaml --- r: 142573 b: refs/heads/try2 c: 8072690 h: refs/heads/master i: 142571: f74453b v: v3
1 parent 4c4b648 commit 4af518a

File tree

3 files changed

+113
-3
lines changed

3 files changed

+113
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: 29d83002a27e6f47759b4a3bfe741fb061107816
8+
refs/heads/try2: 807269041437411df49a9a893c86310283d6eb91
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
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 libc::{c_int, c_void};
12+
use option::Some;
13+
use rt::uv::uvll;
14+
use rt::uv::uvll::UV_ASYNC;
15+
use rt::uv::{Watcher, Loop, NativeHandle, AsyncCallback, NullCallback};
16+
use rt::uv::WatcherInterop;
17+
use rt::uv::status_to_maybe_uv_error;
18+
19+
pub struct AsyncWatcher(*uvll::uv_async_t);
20+
impl Watcher for AsyncWatcher { }
21+
22+
impl AsyncWatcher {
23+
fn new(loop_: &mut Loop, cb: AsyncCallback) -> AsyncWatcher {
24+
unsafe {
25+
let handle = uvll::malloc_handle(UV_ASYNC);
26+
assert!(handle.is_not_null());
27+
let mut watcher: AsyncWatcher = NativeHandle::from_native_handle(handle);
28+
watcher.install_watcher_data();
29+
let data = watcher.get_watcher_data();
30+
data.async_cb = Some(cb);
31+
assert_eq!(0, uvll::async_init(loop_.native_handle(), handle, async_cb));
32+
return watcher;
33+
}
34+
35+
extern fn async_cb(handle: *uvll::uv_async_t, status: c_int) {
36+
let mut watcher: AsyncWatcher = NativeHandle::from_native_handle(handle);
37+
let status = status_to_maybe_uv_error(watcher.native_handle(), status);
38+
let data = watcher.get_watcher_data();
39+
let cb = data.async_cb.get_ref();
40+
(*cb)(watcher, status);
41+
}
42+
}
43+
44+
fn send(&mut self) {
45+
unsafe {
46+
let handle = self.native_handle();
47+
uvll::async_send(handle);
48+
}
49+
}
50+
51+
fn close(self, cb: NullCallback) {
52+
let mut this = self;
53+
let data = this.get_watcher_data();
54+
assert!(data.close_cb.is_none());
55+
data.close_cb = Some(cb);
56+
57+
unsafe {
58+
uvll::close(self.native_handle(), close_cb);
59+
}
60+
61+
extern fn close_cb(handle: *uvll::uv_stream_t) {
62+
let mut watcher: AsyncWatcher = NativeHandle::from_native_handle(handle);
63+
{
64+
let data = watcher.get_watcher_data();
65+
data.close_cb.swap_unwrap()();
66+
}
67+
watcher.drop_watcher_data();
68+
unsafe { uvll::free_handle(handle as *c_void); }
69+
}
70+
}
71+
}
72+
73+
impl NativeHandle<*uvll::uv_async_t> for AsyncWatcher {
74+
fn from_native_handle(handle: *uvll::uv_async_t) -> AsyncWatcher {
75+
AsyncWatcher(handle)
76+
}
77+
fn native_handle(&self) -> *uvll::uv_async_t {
78+
match self { &AsyncWatcher(ptr) => ptr }
79+
}
80+
}
81+
82+
#[cfg(test)]
83+
mod test {
84+
85+
use super::*;
86+
use rt::uv::Loop;
87+
use unstable::run_in_bare_thread;
88+
use rt::thread::Thread;
89+
use cell::Cell;
90+
91+
#[test]
92+
fn smoke_test() {
93+
do run_in_bare_thread {
94+
let mut loop_ = Loop::new();
95+
let watcher = AsyncWatcher::new(&mut loop_, |w, _| w.close(||()) );
96+
let watcher_cell = Cell(watcher);
97+
let _thread = do Thread::start {
98+
let mut watcher = watcher_cell.take();
99+
watcher.send();
100+
};
101+
loop_.run();
102+
loop_.close();
103+
}
104+
}
105+
}

branches/try2/src/libcore/rt/uv/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ pub use self::file::FsRequest;
5757
pub use self::net::{StreamWatcher, TcpWatcher};
5858
pub use self::idle::IdleWatcher;
5959
pub use self::timer::TimerWatcher;
60+
pub use self::async::AsyncWatcher;
6061

6162
/// The implementation of `rtio` for libuv
6263
pub mod uvio;
@@ -68,6 +69,7 @@ pub mod file;
6869
pub mod net;
6970
pub mod idle;
7071
pub mod timer;
72+
pub mod async;
7173

7274
/// XXX: Loop(*handle) is buggy with destructors. Normal structs
7375
/// with dtors may not be destructured, but tuple structs can,
@@ -125,6 +127,7 @@ pub type IdleCallback = ~fn(IdleWatcher, Option<UvError>);
125127
pub type ConnectionCallback = ~fn(StreamWatcher, Option<UvError>);
126128
pub type FsCallback = ~fn(FsRequest, Option<UvError>);
127129
pub type TimerCallback = ~fn(TimerWatcher, Option<UvError>);
130+
pub type AsyncCallback = ~fn(AsyncWatcher, Option<UvError>);
128131

129132

130133
/// Callbacks used by StreamWatchers, set as custom data on the foreign handle
@@ -135,7 +138,8 @@ struct WatcherData {
135138
close_cb: Option<NullCallback>,
136139
alloc_cb: Option<AllocCallback>,
137140
idle_cb: Option<IdleCallback>,
138-
timer_cb: Option<TimerCallback>
141+
timer_cb: Option<TimerCallback>,
142+
async_cb: Option<AsyncCallback>
139143
}
140144

141145
pub trait WatcherInterop {
@@ -164,7 +168,8 @@ impl<H, W: Watcher + NativeHandle<*H>> WatcherInterop for W {
164168
close_cb: None,
165169
alloc_cb: None,
166170
idle_cb: None,
167-
timer_cb: None
171+
timer_cb: None,
172+
async_cb: None
168173
};
169174
let data = transmute::<~WatcherData, *c_void>(data);
170175
uvll::set_data_for_uv_handle(self.native_handle(), data);

0 commit comments

Comments
 (0)