@@ -77,9 +77,7 @@ pub trait Request { }
77
77
/// handle. Watchers are generally created, then `start`ed, `stop`ed
78
78
/// and `close`ed, but due to their complex life cycle may not be
79
79
/// entirely memory safe if used in unanticipated patterns.
80
- pub trait Watcher {
81
- fn event_loop ( & self ) -> Loop ;
82
- }
80
+ pub trait Watcher { }
83
81
84
82
pub type NullCallback = ~fn ( ) ;
85
83
impl Callback for NullCallback { }
@@ -123,12 +121,7 @@ impl NativeHandle<*uvll::uv_loop_t> for Loop {
123
121
}
124
122
125
123
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 { }
132
125
133
126
pub type IdleCallback = ~fn ( IdleWatcher , Option < UvError > ) ;
134
127
impl Callback for IdleCallback { }
@@ -146,14 +139,14 @@ pub impl IdleWatcher {
146
139
147
140
fn start ( & mut self , cb : IdleCallback ) {
148
141
149
- set_watcher_callback ( self , cb) ;
142
+ self . set_callback ( cb) ;
150
143
unsafe {
151
144
assert ! ( 0 == uvll:: idle_start( self . native_handle( ) , idle_cb) )
152
145
} ;
153
146
154
147
extern fn idle_cb ( handle : * uvll:: uv_idle_t , status : c_int ) {
155
148
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 ( ) ;
157
150
let status = status_to_maybe_uv_error ( handle, status) ;
158
151
( * cb) ( idle_watcher, status) ;
159
152
}
@@ -167,9 +160,11 @@ pub impl IdleWatcher {
167
160
unsafe { uvll:: close ( self . native_handle ( ) , close_cb) } ;
168
161
169
162
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
+ }
173
168
}
174
169
}
175
170
}
@@ -224,7 +219,7 @@ fn error_smoke_test() {
224
219
225
220
pub fn last_uv_error<H, W: Watcher + NativeHandle<*H>>(watcher: &W) -> UvError {
226
221
unsafe {
227
- let loop_ = loop_from_watcher( watcher);
222
+ let loop_ = watcher.event_loop( );
228
223
UvError(uvll::last_error(loop_.native_handle()))
229
224
}
230
225
}
@@ -288,111 +283,103 @@ pub fn status_to_maybe_uv_error<T>(handle: *T, status: c_int) -> Option<UvError>
288
283
}
289
284
}
290
285
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>,
298
293
}
299
294
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);
312
303
}
313
304
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_)
326
312
}
327
313
}
328
- }
329
314
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>();
333
321
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
+ }
340
328
}
341
- }
342
329
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
+ }
355
342
}
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
- }
366
343
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
+ }
378
353
}
379
- }
380
354
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
+ }
383
368
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
+ }
388
375
}
389
- }
390
376
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
+ }
396
383
}
397
384
}
398
385
0 commit comments