Skip to content

Commit 6ab02c0

Browse files
committed
core::rt: Convert some uv functions to extension methods
1 parent cfd183d commit 6ab02c0

File tree

3 files changed

+127
-148
lines changed

3 files changed

+127
-148
lines changed

src/libcore/rt/uv/mod.rs

Lines changed: 90 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,7 @@ pub trait Request { }
7777
/// handle. Watchers are generally created, then `start`ed, `stop`ed
7878
/// and `close`ed, but due to their complex life cycle may not be
7979
/// entirely memory safe if used in unanticipated patterns.
80-
pub trait Watcher {
81-
fn event_loop(&self) -> Loop;
82-
}
80+
pub trait Watcher { }
8381

8482
pub type NullCallback = ~fn();
8583
impl Callback for NullCallback { }
@@ -123,12 +121,7 @@ impl NativeHandle<*uvll::uv_loop_t> for Loop {
123121
}
124122

125123
pub struct IdleWatcher(*uvll::uv_idle_t);
126-
127-
impl Watcher for IdleWatcher {
128-
fn event_loop(&self) -> Loop {
129-
loop_from_watcher(self)
130-
}
131-
}
124+
impl Watcher for IdleWatcher { }
132125

133126
pub type IdleCallback = ~fn(IdleWatcher, Option<UvError>);
134127
impl Callback for IdleCallback { }
@@ -146,14 +139,14 @@ pub impl IdleWatcher {
146139

147140
fn start(&mut self, cb: IdleCallback) {
148141

149-
set_watcher_callback(self, cb);
142+
self.set_callback(cb);
150143
unsafe {
151144
assert!(0 == uvll::idle_start(self.native_handle(), idle_cb))
152145
};
153146

154147
extern fn idle_cb(handle: *uvll::uv_idle_t, status: c_int) {
155148
let idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
156-
let cb: &IdleCallback = borrow_callback_from_watcher(&idle_watcher);
149+
let cb: &IdleCallback = idle_watcher.borrow_callback();
157150
let status = status_to_maybe_uv_error(handle, status);
158151
(*cb)(idle_watcher, status);
159152
}
@@ -167,9 +160,11 @@ pub impl IdleWatcher {
167160
unsafe { uvll::close(self.native_handle(), close_cb) };
168161

169162
extern fn close_cb(handle: *uvll::uv_idle_t) {
170-
let mut idle_watcher = NativeHandle::from_native_handle(handle);
171-
drop_watcher_callback::<uvll::uv_idle_t, IdleWatcher, IdleCallback>(&mut idle_watcher);
172-
unsafe { uvll::idle_delete(handle) };
163+
unsafe {
164+
let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
165+
idle_watcher.drop_callback::<IdleCallback>();
166+
uvll::idle_delete(handle);
167+
}
173168
}
174169
}
175170
}
@@ -224,7 +219,7 @@ fn error_smoke_test() {
224219
225220
pub fn last_uv_error<H, W: Watcher + NativeHandle<*H>>(watcher: &W) -> UvError {
226221
unsafe {
227-
let loop_ = loop_from_watcher(watcher);
222+
let loop_ = watcher.event_loop();
228223
UvError(uvll::last_error(loop_.native_handle()))
229224
}
230225
}
@@ -288,111 +283,103 @@ pub fn status_to_maybe_uv_error<T>(handle: *T, status: c_int) -> Option<UvError>
288283
}
289284
}
290285
291-
/// Get the uv event loop from a Watcher
292-
pub fn loop_from_watcher<H, W: Watcher + NativeHandle<*H>>(
293-
watcher: &W) -> Loop {
294-
295-
let handle = watcher.native_handle();
296-
let loop_ = unsafe { uvll::get_loop_for_uv_handle(handle) };
297-
NativeHandle::from_native_handle(loop_)
286+
/// Callbacks used by StreamWatchers, set as custom data on the foreign handle
287+
struct WatcherData {
288+
read_cb: Option<ReadCallback>,
289+
write_cb: Option<ConnectionCallback>,
290+
connect_cb: Option<ConnectionCallback>,
291+
close_cb: Option<NullCallback>,
292+
alloc_cb: Option<AllocCallback>,
298293
}
299294
300-
/// Set the custom data on a handle to a callback Note: This is only
301-
/// suitable for watchers that make just one type of callback. For
302-
/// others use WatcherData
303-
pub fn set_watcher_callback<H, W: Watcher + NativeHandle<*H>, CB: Callback>(
304-
watcher: &mut W, cb: CB) {
305-
306-
drop_watcher_callback::<H, W, CB>(watcher);
307-
// XXX: Boxing the callback so it fits into a
308-
// pointer. Unfortunate extra allocation
309-
let boxed_cb = ~cb;
310-
let data = unsafe { transmute::<~CB, *c_void>(boxed_cb) };
311-
unsafe { uvll::set_data_for_uv_handle(watcher.native_handle(), data) };
295+
pub trait WatcherInterop {
296+
fn event_loop(&self) -> Loop;
297+
fn set_callback<CB: Callback>(&mut self, cb: CB);
298+
fn drop_callback<CB: Callback>(&mut self);
299+
fn borrow_callback<CB: Callback>(&self) -> &CB;
300+
fn install_watcher_data(&mut self);
301+
fn get_watcher_data<'r>(&'r mut self) -> &'r mut WatcherData;
302+
fn drop_watcher_data(&mut self);
312303
}
313304
314-
/// Delete a callback from a handle's custom data
315-
pub fn drop_watcher_callback<H, W: Watcher + NativeHandle<*H>, CB: Callback>(
316-
watcher: &mut W) {
317-
318-
unsafe {
319-
let handle = watcher.native_handle();
320-
let handle_data: *c_void = uvll::get_data_for_uv_handle(handle);
321-
if handle_data.is_not_null() {
322-
// Take ownership of the callback and drop it
323-
let _cb = transmute::<*c_void, ~CB>(handle_data);
324-
// Make sure the pointer is zeroed
325-
uvll::set_data_for_uv_handle(watcher.native_handle(), null::<()>());
305+
impl<H, W: Watcher + NativeHandle<*H>> WatcherInterop for W {
306+
/// Get the uv event loop from a Watcher
307+
pub fn event_loop(&self) -> Loop {
308+
unsafe {
309+
let handle = self.native_handle();
310+
let loop_ = uvll::get_loop_for_uv_handle(handle);
311+
NativeHandle::from_native_handle(loop_)
326312
}
327313
}
328-
}
329314
330-
/// Take a pointer to the callback installed as custom data
331-
pub fn borrow_callback_from_watcher<H, W: Watcher + NativeHandle<*H>,
332-
CB: Callback>(watcher: &W) -> &CB {
315+
/// Set the custom data on a handle to a callback Note: This is only
316+
/// suitable for watchers that make just one type of callback. For
317+
/// others use WatcherData
318+
pub fn set_callback<CB: Callback>(&mut self, cb: CB) {
319+
unsafe {
320+
self.drop_callback::<CB>();
333321
334-
unsafe {
335-
let handle = watcher.native_handle();
336-
let handle_data: *c_void = uvll::get_data_for_uv_handle(handle);
337-
assert!(handle_data.is_not_null());
338-
let cb = transmute::<&*c_void, &~CB>(&handle_data);
339-
return &**cb;
322+
// XXX: Boxing the callback so it fits into a
323+
// pointer. Unfortunate extra allocation
324+
let boxed_cb = ~cb;
325+
let data = transmute::<~CB, *c_void>(boxed_cb);
326+
uvll::set_data_for_uv_handle(self.native_handle(), data);
327+
}
340328
}
341-
}
342329
343-
/// Take ownership of the callback installed as custom data
344-
pub fn take_callback_from_watcher<H, W: Watcher + NativeHandle<*H>, CB: Callback>(
345-
watcher: &mut W) -> CB {
346-
347-
unsafe {
348-
let handle = watcher.native_handle();
349-
let handle_data: *c_void = uvll::get_data_for_uv_handle(handle);
350-
assert!(handle_data.is_not_null());
351-
uvll::set_data_for_uv_handle(handle, null::<()>());
352-
let cb: ~CB = transmute::<*c_void, ~CB>(handle_data);
353-
let cb = match cb { ~cb => cb };
354-
return cb;
330+
/// Delete a callback from a handle's custom data
331+
pub fn drop_callback<CB: Callback>(&mut self) {
332+
unsafe {
333+
let handle = self.native_handle();
334+
let handle_data: *c_void = uvll::get_data_for_uv_handle(handle);
335+
if handle_data.is_not_null() {
336+
// Take ownership of the callback and drop it
337+
let _cb = transmute::<*c_void, ~CB>(handle_data);
338+
// Make sure the pointer is zeroed
339+
uvll::set_data_for_uv_handle(self.native_handle(), null::<()>());
340+
}
341+
}
355342
}
356-
}
357-
358-
/// Callbacks used by StreamWatchers, set as custom data on the foreign handle
359-
struct WatcherData {
360-
read_cb: Option<ReadCallback>,
361-
write_cb: Option<ConnectionCallback>,
362-
connect_cb: Option<ConnectionCallback>,
363-
close_cb: Option<NullCallback>,
364-
alloc_cb: Option<AllocCallback>,
365-
}
366343
367-
pub fn install_watcher_data<H, W: Watcher + NativeHandle<*H>>(watcher: &mut W) {
368-
unsafe {
369-
let data = ~WatcherData {
370-
read_cb: None,
371-
write_cb: None,
372-
connect_cb: None,
373-
close_cb: None,
374-
alloc_cb: None,
375-
};
376-
let data = transmute::<~WatcherData, *c_void>(data);
377-
uvll::set_data_for_uv_handle(watcher.native_handle(), data);
344+
/// Take a pointer to the callback installed as custom data
345+
pub fn borrow_callback<CB: Callback>(&self) -> &CB {
346+
unsafe {
347+
let handle = self.native_handle();
348+
let handle_data: *c_void = uvll::get_data_for_uv_handle(handle);
349+
assert!(handle_data.is_not_null());
350+
let cb = transmute::<&*c_void, &~CB>(&handle_data);
351+
return &**cb;
352+
}
378353
}
379-
}
380354
381-
pub fn get_watcher_data<'r, H, W: Watcher + NativeHandle<*H>>(
382-
watcher: &'r mut W) -> &'r mut WatcherData {
355+
pub fn install_watcher_data(&mut self) {
356+
unsafe {
357+
let data = ~WatcherData {
358+
read_cb: None,
359+
write_cb: None,
360+
connect_cb: None,
361+
close_cb: None,
362+
alloc_cb: None,
363+
};
364+
let data = transmute::<~WatcherData, *c_void>(data);
365+
uvll::set_data_for_uv_handle(self.native_handle(), data);
366+
}
367+
}
383368
384-
unsafe {
385-
let data = uvll::get_data_for_uv_handle(watcher.native_handle());
386-
let data = transmute::<&*c_void, &mut ~WatcherData>(&data);
387-
return &mut **data;
369+
pub fn get_watcher_data<'r>(&'r mut self) -> &'r mut WatcherData {
370+
unsafe {
371+
let data = uvll::get_data_for_uv_handle(self.native_handle());
372+
let data = transmute::<&*c_void, &mut ~WatcherData>(&data);
373+
return &mut **data;
374+
}
388375
}
389-
}
390376
391-
pub fn drop_watcher_data<H, W: Watcher + NativeHandle<*H>>(watcher: &mut W) {
392-
unsafe {
393-
let data = uvll::get_data_for_uv_handle(watcher.native_handle());
394-
let _data = transmute::<*c_void, ~WatcherData>(data);
395-
uvll::set_data_for_uv_handle(watcher.native_handle(), null::<()>());
377+
pub fn drop_watcher_data(&mut self) {
378+
unsafe {
379+
let data = uvll::get_data_for_uv_handle(self.native_handle());
380+
let _data = transmute::<*c_void, ~WatcherData>(data);
381+
uvll::set_data_for_uv_handle(self.native_handle(), null::<()>());
382+
}
396383
}
397384
}
398385

0 commit comments

Comments
 (0)