@@ -54,19 +54,18 @@ use std::libc::{c_void, c_int, size_t, malloc, free};
54
54
use std:: cast:: transmute;
55
55
use std:: ptr:: null;
56
56
use std:: unstable:: finally:: Finally ;
57
- use std:: rt:: io:: net:: ip:: SocketAddr ;
58
57
59
58
use std:: rt:: io:: IoError ;
60
59
61
60
//#[cfg(test)] use unstable::run_in_bare_thread;
62
61
63
62
pub use self :: file:: { FsRequest , FileWatcher } ;
64
- pub use self :: net:: { StreamWatcher , TcpWatcher , UdpWatcher } ;
63
+ pub use self :: net:: { TcpWatcher , TcpListener , TcpAcceptor , UdpWatcher } ;
65
64
pub use self :: idle:: IdleWatcher ;
66
65
pub use self :: timer:: TimerWatcher ;
67
66
pub use self :: async:: AsyncWatcher ;
68
67
pub use self :: process:: Process ;
69
- pub use self :: pipe:: PipeWatcher ;
68
+ pub use self :: pipe:: { PipeWatcher , PipeListener , PipeAcceptor } ;
70
69
pub use self :: signal:: SignalWatcher ;
71
70
pub use self :: tty:: TtyWatcher ;
72
71
@@ -97,24 +96,6 @@ pub struct Loop {
97
96
priv handle : * uvll:: uv_loop_t
98
97
}
99
98
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
-
118
99
/// A type that wraps a native handle
119
100
pub trait NativeHandle < T > {
120
101
fn from_native_handle ( T ) -> Self ;
@@ -160,32 +141,47 @@ pub trait UvHandle<T> {
160
141
}
161
142
}
162
143
163
- pub trait UvRequest < T > {
164
- fn uv_request ( & self ) -> * T ;
144
+ pub struct Request {
145
+ handle : * uvll:: uv_req_t ,
146
+ }
165
147
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) } )
173
151
}
174
152
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 }
177
155
}
178
156
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) }
185
159
}
186
160
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
+ }
189
185
}
190
186
}
191
187
@@ -214,110 +210,6 @@ impl NativeHandle<*uvll::uv_loop_t> for Loop {
214
210
}
215
211
}
216
212
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
-
321
213
// XXX: Need to define the error constants like EOF so they can be
322
214
// compared to the UvError type
323
215
0 commit comments