@@ -18,67 +18,20 @@ use crate::sys_common::IntoInner;
18
18
// Anonymous pipes
19
19
////////////////////////////////////////////////////////////////////////////////
20
20
21
- // A 64kb pipe capacity is the same as a typical Linux default.
22
- const PIPE_BUFFER_CAPACITY : u32 = 64 * 1024 ;
23
-
24
- pub enum AnonPipe {
25
- Sync ( Handle ) ,
26
- Async ( Handle ) ,
21
+ pub struct AnonPipe {
22
+ inner : Handle ,
27
23
}
28
24
29
25
impl IntoInner < Handle > for AnonPipe {
30
26
fn into_inner ( self ) -> Handle {
31
- match self {
32
- Self :: Sync ( handle) => handle,
33
- Self :: Async ( handle) => handle,
34
- }
27
+ self . inner
35
28
}
36
29
}
37
30
38
31
pub struct Pipes {
39
32
pub ours : AnonPipe ,
40
33
pub theirs : AnonPipe ,
41
34
}
42
- impl Pipes {
43
- /// Create a new pair of pipes where both pipes are synchronous.
44
- ///
45
- /// These must not be used asynchronously.
46
- pub fn new_synchronous (
47
- ours_readable : bool ,
48
- their_handle_inheritable : bool ,
49
- ) -> io:: Result < Self > {
50
- unsafe {
51
- // If `CreatePipe` succeeds, these will be our pipes.
52
- let mut read = ptr:: null_mut ( ) ;
53
- let mut write = ptr:: null_mut ( ) ;
54
-
55
- if c:: CreatePipe ( & mut read, & mut write, ptr:: null ( ) , PIPE_BUFFER_CAPACITY ) == 0 {
56
- Err ( io:: Error :: last_os_error ( ) )
57
- } else {
58
- let ( ours, theirs) = if ours_readable { ( read, write) } else { ( write, read) } ;
59
- let ours = Handle :: from_raw_handle ( ours) ;
60
- #[ cfg( not( target_vendor = "uwp" ) ) ]
61
- let theirs = Handle :: from_raw_handle ( theirs) ;
62
- #[ cfg( target_vendor = "uwp" ) ]
63
- let mut theirs = Handle :: from_raw_handle ( theirs) ;
64
-
65
- if their_handle_inheritable {
66
- #[ cfg( not( target_vendor = "uwp" ) ) ]
67
- {
68
- theirs. set_inheritable ( ) ?;
69
- }
70
-
71
- #[ cfg( target_vendor = "uwp" ) ]
72
- {
73
- theirs = theirs. duplicate ( 0 , true , c:: DUPLICATE_SAME_ACCESS ) ?;
74
- }
75
- }
76
-
77
- Ok ( Pipes { ours : AnonPipe :: Sync ( ours) , theirs : AnonPipe :: Sync ( theirs) } )
78
- }
79
- }
80
- }
81
- }
82
35
83
36
/// Although this looks similar to `anon_pipe` in the Unix module it's actually
84
37
/// subtly different. Here we'll return two pipes in the `Pipes` return value,
@@ -100,6 +53,9 @@ impl Pipes {
100
53
/// with `OVERLAPPED` instances, but also works out ok if it's only ever used
101
54
/// once at a time (which we do indeed guarantee).
102
55
pub fn anon_pipe ( ours_readable : bool , their_handle_inheritable : bool ) -> io:: Result < Pipes > {
56
+ // A 64kb pipe capacity is the same as a typical Linux default.
57
+ const PIPE_BUFFER_CAPACITY : u32 = 64 * 1024 ;
58
+
103
59
// Note that we specifically do *not* use `CreatePipe` here because
104
60
// unfortunately the anonymous pipes returned do not support overlapped
105
61
// operations. Instead, we create a "hopefully unique" name and create a
@@ -200,9 +156,12 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
200
156
} ;
201
157
opts. security_attributes ( & mut sa) ;
202
158
let theirs = File :: open ( Path :: new ( & name) , & opts) ?;
203
- let theirs = AnonPipe :: Sync ( theirs. into_inner ( ) ) ;
159
+ let theirs = AnonPipe { inner : theirs. into_inner ( ) } ;
204
160
205
- Ok ( Pipes { ours : AnonPipe :: Async ( ours) , theirs } )
161
+ Ok ( Pipes {
162
+ ours : AnonPipe { inner : ours } ,
163
+ theirs : AnonPipe { inner : theirs. into_inner ( ) } ,
164
+ } )
206
165
}
207
166
}
208
167
@@ -212,12 +171,12 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
212
171
/// This is achieved by creating a new set of pipes and spawning a thread that
213
172
/// relays messages between the source and the synchronous pipe.
214
173
pub fn spawn_pipe_relay (
215
- source : & Handle ,
174
+ source : & AnonPipe ,
216
175
ours_readable : bool ,
217
176
their_handle_inheritable : bool ,
218
177
) -> io:: Result < AnonPipe > {
219
178
// We need this handle to live for the lifetime of the thread spawned below.
220
- let source = AnonPipe :: Async ( source. duplicate ( 0 , true , c :: DUPLICATE_SAME_ACCESS ) ? ) ;
179
+ let source = source. duplicate ( ) ? ;
221
180
222
181
// create a new pair of anon pipes.
223
182
let Pipes { theirs, ours } = anon_pipe ( ours_readable, their_handle_inheritable) ?;
@@ -268,24 +227,19 @@ type AlertableIoFn = unsafe extern "system" fn(
268
227
269
228
impl AnonPipe {
270
229
pub fn handle ( & self ) -> & Handle {
271
- match self {
272
- Self :: Async ( ref handle) => handle,
273
- Self :: Sync ( ref handle) => handle,
274
- }
230
+ & self . inner
275
231
}
276
232
pub fn into_handle ( self ) -> Handle {
277
- self . into_inner ( )
233
+ self . inner
234
+ }
235
+ fn duplicate ( & self ) -> io:: Result < Self > {
236
+ self . inner . duplicate ( 0 , false , c:: DUPLICATE_SAME_ACCESS ) . map ( |inner| AnonPipe { inner } )
278
237
}
279
238
280
239
pub fn read ( & self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
281
240
let result = unsafe {
282
241
let len = crate :: cmp:: min ( buf. len ( ) , c:: DWORD :: MAX as usize ) as c:: DWORD ;
283
- match self {
284
- Self :: Sync ( ref handle) => handle. read ( buf) ,
285
- Self :: Async ( _) => {
286
- self . alertable_io_internal ( c:: ReadFileEx , buf. as_mut_ptr ( ) as _ , len)
287
- }
288
- }
242
+ self . alertable_io_internal ( c:: ReadFileEx , buf. as_mut_ptr ( ) as _ , len)
289
243
} ;
290
244
291
245
match result {
@@ -299,33 +253,28 @@ impl AnonPipe {
299
253
}
300
254
301
255
pub fn read_vectored ( & self , bufs : & mut [ IoSliceMut < ' _ > ] ) -> io:: Result < usize > {
302
- io :: default_read_vectored ( |buf| self . read ( buf ) , bufs)
256
+ self . inner . read_vectored ( bufs)
303
257
}
304
258
305
259
#[ inline]
306
260
pub fn is_read_vectored ( & self ) -> bool {
307
- false
261
+ self . inner . is_read_vectored ( )
308
262
}
309
263
310
264
pub fn write ( & self , buf : & [ u8 ] ) -> io:: Result < usize > {
311
265
unsafe {
312
266
let len = crate :: cmp:: min ( buf. len ( ) , c:: DWORD :: MAX as usize ) as c:: DWORD ;
313
- match self {
314
- Self :: Sync ( ref handle) => handle. write ( buf) ,
315
- Self :: Async ( _) => {
316
- self . alertable_io_internal ( c:: WriteFileEx , buf. as_ptr ( ) as _ , len)
317
- }
318
- }
267
+ self . alertable_io_internal ( c:: WriteFileEx , buf. as_ptr ( ) as _ , len)
319
268
}
320
269
}
321
270
322
271
pub fn write_vectored ( & self , bufs : & [ IoSlice < ' _ > ] ) -> io:: Result < usize > {
323
- io :: default_write_vectored ( |buf| self . write ( buf ) , bufs)
272
+ self . inner . write_vectored ( bufs)
324
273
}
325
274
326
275
#[ inline]
327
276
pub fn is_write_vectored ( & self ) -> bool {
328
- false
277
+ self . inner . is_write_vectored ( )
329
278
}
330
279
331
280
/// Synchronizes asynchronous reads or writes using our anonymous pipe.
@@ -397,7 +346,7 @@ impl AnonPipe {
397
346
398
347
// Asynchronous read of the pipe.
399
348
// If successful, `callback` will be called once it completes.
400
- let result = io ( self . handle ( ) . as_handle ( ) , buf, len, & mut overlapped, callback) ;
349
+ let result = io ( self . inner . as_handle ( ) , buf, len, & mut overlapped, callback) ;
401
350
if result == c:: FALSE {
402
351
// We can return here because the call failed.
403
352
// After this we must not return until the I/O completes.
0 commit comments