Skip to content

Commit b0554d3

Browse files
committed
---
yaml --- r: 95993 b: refs/heads/dist-snap c: 584b359 h: refs/heads/master i: 95991: 795bf10 v: v3
1 parent 6ef2045 commit b0554d3

File tree

10 files changed

+619
-1068
lines changed

10 files changed

+619
-1068
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: c274a6888410ce3e357e014568b43310ed787d36
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
9-
refs/heads/dist-snap: 5842b606a7e11c671d92aac574389e359a8172f6
9+
refs/heads/dist-snap: 584b3593485ef144de7217de19ac8a98766c0532
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1212
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/src/librustuv/addrinfo.rs

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,9 @@ use std::rt::local::Local;
1717
use std::rt::sched::Scheduler;
1818

1919
use net;
20-
use super::{Loop, UvError, NativeHandle};
21-
use uvll::UV_GETADDRINFO;
20+
use super::{Loop, UvError, NativeHandle, Request};
2221
use uvll;
2322

24-
struct GetAddrInfoRequest {
25-
handle: *uvll::uv_getaddrinfo_t,
26-
}
27-
2823
struct Addrinfo {
2924
handle: *uvll::addrinfo,
3025
}
@@ -35,13 +30,9 @@ struct Ctx {
3530
addrinfo: Option<Addrinfo>,
3631
}
3732

38-
impl GetAddrInfoRequest {
39-
pub fn new() -> GetAddrInfoRequest {
40-
GetAddrInfoRequest {
41-
handle: unsafe { uvll::malloc_req(uvll::UV_GETADDRINFO) },
42-
}
43-
}
33+
pub struct GetAddrInfoRequest;
4434

35+
impl GetAddrInfoRequest {
4536
pub fn run(loop_: &Loop, node: Option<&str>, service: Option<&str>,
4637
hints: Option<ai::Hint>) -> Result<~[ai::Info], UvError> {
4738
assert!(node.is_some() || service.is_some());
@@ -85,7 +76,7 @@ impl GetAddrInfoRequest {
8576
}
8677
});
8778
let hint_ptr = hint.as_ref().map_default(null(), |x| x as *uvll::addrinfo);
88-
let req = GetAddrInfoRequest::new();
79+
let req = Request::new(uvll::UV_GETADDRINFO);
8980

9081
return match unsafe {
9182
uvll::uv_getaddrinfo(loop_.native_handle(), req.handle,
@@ -94,7 +85,8 @@ impl GetAddrInfoRequest {
9485
} {
9586
0 => {
9687
let mut cx = Ctx { slot: None, status: 0, addrinfo: None };
97-
unsafe { uvll::set_data_for_req(req.handle, &cx) }
88+
req.set_data(&cx);
89+
req.defuse();
9890
let scheduler: ~Scheduler = Local::take();
9991
do scheduler.deschedule_running_task_and_then |_, task| {
10092
cx.slot = Some(task);
@@ -112,9 +104,9 @@ impl GetAddrInfoRequest {
112104
extern fn getaddrinfo_cb(req: *uvll::uv_getaddrinfo_t,
113105
status: c_int,
114106
res: *uvll::addrinfo) {
115-
let cx: &mut Ctx = unsafe {
116-
cast::transmute(uvll::get_data_for_req(req))
117-
};
107+
let req = Request::wrap(req);
108+
if status == uvll::ECANCELED { return }
109+
let cx: &mut Ctx = unsafe { cast::transmute(req.get_data()) };
118110
cx.status = status;
119111
cx.addrinfo = Some(Addrinfo { handle: res });
120112

@@ -124,12 +116,6 @@ impl GetAddrInfoRequest {
124116
}
125117
}
126118

127-
impl Drop for GetAddrInfoRequest {
128-
fn drop(&mut self) {
129-
unsafe { uvll::free_req(self.handle) }
130-
}
131-
}
132-
133119
impl Drop for Addrinfo {
134120
fn drop(&mut self) {
135121
unsafe { uvll::uv_freeaddrinfo(self.handle) }

branches/dist-snap/src/librustuv/lib.rs

Lines changed: 36 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,18 @@ use std::libc::{c_void, c_int, size_t, malloc, free};
5454
use std::cast::transmute;
5555
use std::ptr::null;
5656
use std::unstable::finally::Finally;
57-
use std::rt::io::net::ip::SocketAddr;
5857

5958
use std::rt::io::IoError;
6059

6160
//#[cfg(test)] use unstable::run_in_bare_thread;
6261

6362
pub use self::file::{FsRequest, FileWatcher};
64-
pub use self::net::{StreamWatcher, TcpWatcher, UdpWatcher};
63+
pub use self::net::{TcpWatcher, TcpListener, TcpAcceptor, UdpWatcher};
6564
pub use self::idle::IdleWatcher;
6665
pub use self::timer::TimerWatcher;
6766
pub use self::async::AsyncWatcher;
6867
pub use self::process::Process;
69-
pub use self::pipe::PipeWatcher;
68+
pub use self::pipe::{PipeWatcher, PipeListener, PipeAcceptor};
7069
pub use self::signal::SignalWatcher;
7170
pub use self::tty::TtyWatcher;
7271

@@ -97,24 +96,6 @@ pub struct Loop {
9796
priv handle: *uvll::uv_loop_t
9897
}
9998

100-
pub struct Handle(*uvll::uv_handle_t);
101-
102-
impl Watcher for Handle {}
103-
impl NativeHandle<*uvll::uv_handle_t> for Handle {
104-
fn from_native_handle(h: *uvll::uv_handle_t) -> Handle { Handle(h) }
105-
fn native_handle(&self) -> *uvll::uv_handle_t { **self }
106-
}
107-
108-
/// The trait implemented by uv 'watchers' (handles). Watchers are
109-
/// non-owning wrappers around the uv handles and are not completely
110-
/// safe - there may be multiple instances for a single underlying
111-
/// handle. Watchers are generally created, then `start`ed, `stop`ed
112-
/// and `close`ed, but due to their complex life cycle may not be
113-
/// entirely memory safe if used in unanticipated patterns.
114-
pub trait Watcher { }
115-
116-
pub trait Request { }
117-
11899
/// A type that wraps a native handle
119100
pub trait NativeHandle<T> {
120101
fn from_native_handle(T) -> Self;
@@ -160,32 +141,47 @@ pub trait UvHandle<T> {
160141
}
161142
}
162143

163-
pub trait UvRequest<T> {
164-
fn uv_request(&self) -> *T;
144+
pub struct Request {
145+
handle: *uvll::uv_req_t,
146+
}
165147

166-
// FIXME(#8888) dummy self
167-
fn alloc(_: Option<Self>, ty: uvll::uv_req_type) -> *T {
168-
unsafe {
169-
let handle = uvll::malloc_req(ty);
170-
assert!(!handle.is_null());
171-
handle as *T
172-
}
148+
impl Request {
149+
pub fn new(ty: uvll::uv_req_type) -> Request {
150+
Request::wrap(unsafe { uvll::malloc_req(ty) })
173151
}
174152

175-
unsafe fn from_uv_request<'a>(h: &'a *T) -> &'a mut Self {
176-
cast::transmute(uvll::get_data_for_req(*h))
153+
pub fn wrap(handle: *uvll::uv_req_t) -> Request {
154+
Request { handle: handle }
177155
}
178156

179-
fn install(~self) -> ~Self {
180-
unsafe {
181-
let myptr = cast::transmute::<&~Self, &*u8>(&self);
182-
uvll::set_data_for_req(self.uv_request(), *myptr);
183-
}
184-
self
157+
pub fn set_data<T>(&self, t: *T) {
158+
unsafe { uvll::set_data_for_req(self.handle, t) }
185159
}
186160

187-
fn delete(&mut self) {
188-
unsafe { uvll::free_req(self.uv_request() as *c_void) }
161+
pub fn get_data(&self) -> *c_void {
162+
unsafe { uvll::get_data_for_req(self.handle) }
163+
}
164+
165+
// This function should be used when the request handle has been given to an
166+
// underlying uv function, and the uv function has succeeded. This means
167+
// that uv will at some point invoke the callback, and in the meantime we
168+
// can't deallocate the handle because libuv could be using it.
169+
//
170+
// This is still a problem in blocking situations due to linked failure. In
171+
// the connection callback the handle should be re-wrapped with the `wrap`
172+
// function to ensure its destruction.
173+
pub fn defuse(mut self) {
174+
self.handle = ptr::null();
175+
}
176+
}
177+
178+
impl Drop for Request {
179+
fn drop(&mut self) {
180+
unsafe {
181+
if self.handle != ptr::null() {
182+
uvll::free_req(self.handle)
183+
}
184+
}
189185
}
190186
}
191187

@@ -214,110 +210,6 @@ impl NativeHandle<*uvll::uv_loop_t> for Loop {
214210
}
215211
}
216212

217-
// XXX: The uv alloc callback also has a *uv_handle_t arg
218-
pub type AllocCallback = ~fn(uint) -> Buf;
219-
pub type ReadCallback = ~fn(StreamWatcher, int, Buf, Option<UvError>);
220-
pub type NullCallback = ~fn();
221-
pub type ConnectionCallback = ~fn(StreamWatcher, Option<UvError>);
222-
pub type UdpReceiveCallback = ~fn(UdpWatcher, int, Buf, SocketAddr, uint, Option<UvError>);
223-
pub type UdpSendCallback = ~fn(UdpWatcher, Option<UvError>);
224-
225-
226-
/// Callbacks used by StreamWatchers, set as custom data on the foreign handle.
227-
/// XXX: Would be better not to have all watchers allocate room for all callback types.
228-
struct WatcherData {
229-
read_cb: Option<ReadCallback>,
230-
write_cb: Option<ConnectionCallback>,
231-
connect_cb: Option<ConnectionCallback>,
232-
close_cb: Option<NullCallback>,
233-
alloc_cb: Option<AllocCallback>,
234-
udp_recv_cb: Option<UdpReceiveCallback>,
235-
udp_send_cb: Option<UdpSendCallback>,
236-
}
237-
238-
pub trait WatcherInterop {
239-
fn event_loop(&self) -> Loop;
240-
fn install_watcher_data(&mut self);
241-
fn get_watcher_data<'r>(&'r mut self) -> &'r mut WatcherData;
242-
fn drop_watcher_data(&mut self);
243-
fn close(self, cb: NullCallback);
244-
fn close_async(self);
245-
}
246-
247-
impl<H, W: Watcher + NativeHandle<*H>> WatcherInterop for W {
248-
/// Get the uv event loop from a Watcher
249-
fn event_loop(&self) -> Loop {
250-
unsafe {
251-
let handle = self.native_handle();
252-
let loop_ = uvll::get_loop_for_uv_handle(handle);
253-
NativeHandle::from_native_handle(loop_)
254-
}
255-
}
256-
257-
fn install_watcher_data(&mut self) {
258-
unsafe {
259-
let data = ~WatcherData {
260-
read_cb: None,
261-
write_cb: None,
262-
connect_cb: None,
263-
close_cb: None,
264-
alloc_cb: None,
265-
udp_recv_cb: None,
266-
udp_send_cb: None,
267-
};
268-
let data = transmute::<~WatcherData, *c_void>(data);
269-
uvll::set_data_for_uv_handle(self.native_handle(), data);
270-
}
271-
}
272-
273-
fn get_watcher_data<'r>(&'r mut self) -> &'r mut WatcherData {
274-
unsafe {
275-
let data = uvll::get_data_for_uv_handle(self.native_handle());
276-
let data = transmute::<&*c_void, &mut ~WatcherData>(&data);
277-
return &mut **data;
278-
}
279-
}
280-
281-
fn drop_watcher_data(&mut self) {
282-
unsafe {
283-
let data = uvll::get_data_for_uv_handle(self.native_handle());
284-
let _data = transmute::<*c_void, ~WatcherData>(data);
285-
uvll::set_data_for_uv_handle(self.native_handle(), null::<()>());
286-
}
287-
}
288-
289-
fn close(mut self, cb: NullCallback) {
290-
{
291-
let data = self.get_watcher_data();
292-
assert!(data.close_cb.is_none());
293-
data.close_cb = Some(cb);
294-
}
295-
296-
unsafe {
297-
uvll::uv_close(self.native_handle() as *uvll::uv_handle_t, close_cb);
298-
}
299-
300-
extern fn close_cb(handle: *uvll::uv_handle_t) {
301-
let mut h: Handle = NativeHandle::from_native_handle(handle);
302-
h.get_watcher_data().close_cb.take_unwrap()();
303-
h.drop_watcher_data();
304-
unsafe { uvll::free_handle(handle as *c_void) }
305-
}
306-
}
307-
308-
fn close_async(self) {
309-
unsafe {
310-
uvll::uv_close(self.native_handle() as *uvll::uv_handle_t, close_cb);
311-
}
312-
313-
extern fn close_cb(handle: *uvll::uv_handle_t) {
314-
let mut h: Handle = NativeHandle::from_native_handle(handle);
315-
h.drop_watcher_data();
316-
unsafe { uvll::free_handle(handle as *c_void) }
317-
}
318-
}
319-
}
320-
321213
// XXX: Need to define the error constants like EOF so they can be
322214
// compared to the UvError type
323215

0 commit comments

Comments
 (0)