@@ -18,56 +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
- let theirs = Handle::from_raw_handle(theirs);
61
-
62
- if their_handle_inheritable {
63
- theirs.set_inheritable()?;
64
- }
65
-
66
- Ok(Pipes { ours: AnonPipe::Sync(ours), theirs: AnonPipe::Sync(theirs) })
67
- }
68
- }
69
- }
70
- }
71
35
72
36
/// Although this looks similar to `anon_pipe` in the Unix module it's actually
73
37
/// subtly different. Here we'll return two pipes in the `Pipes` return value,
@@ -89,6 +53,9 @@ impl Pipes {
89
53
/// with `OVERLAPPED` instances, but also works out ok if it's only ever used
90
54
/// once at a time (which we do indeed guarantee).
91
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
+
92
59
// Note that we specifically do *not* use `CreatePipe` here because
93
60
// unfortunately the anonymous pipes returned do not support overlapped
94
61
// operations. Instead, we create a "hopefully unique" name and create a
@@ -189,9 +156,12 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
189
156
};
190
157
opts.security_attributes(&mut sa);
191
158
let theirs = File::open(Path::new(&name), &opts)?;
192
- let theirs = AnonPipe::Sync( theirs.into_inner()) ;
159
+ let theirs = AnonPipe { inner: theirs.into_inner() } ;
193
160
194
- Ok(Pipes { ours: AnonPipe::Async(ours), theirs })
161
+ Ok(Pipes {
162
+ ours: AnonPipe { inner: ours },
163
+ theirs: AnonPipe { inner: theirs.into_inner() },
164
+ })
195
165
}
196
166
}
197
167
@@ -201,12 +171,12 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
201
171
/// This is achieved by creating a new set of pipes and spawning a thread that
202
172
/// relays messages between the source and the synchronous pipe.
203
173
pub fn spawn_pipe_relay(
204
- source: &Handle ,
174
+ source: &AnonPipe ,
205
175
ours_readable: bool,
206
176
their_handle_inheritable: bool,
207
177
) -> io::Result<AnonPipe> {
208
178
// We need this handle to live for the lifetime of the thread spawned below.
209
- let source = AnonPipe::Async( source.duplicate(0, true, c::DUPLICATE_SAME_ACCESS)?) ;
179
+ let source = source.duplicate()? ;
210
180
211
181
// create a new pair of anon pipes.
212
182
let Pipes { theirs, ours } = anon_pipe(ours_readable, their_handle_inheritable)?;
@@ -257,24 +227,19 @@ type AlertableIoFn = unsafe extern "system" fn(
257
227
258
228
impl AnonPipe {
259
229
pub fn handle(&self) -> &Handle {
260
- match self {
261
- Self::Async(ref handle) => handle,
262
- Self::Sync(ref handle) => handle,
263
- }
230
+ &self.inner
264
231
}
265
232
pub fn into_handle(self) -> Handle {
266
- 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 })
267
237
}
268
238
269
239
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
270
240
let result = unsafe {
271
241
let len = crate::cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD;
272
- match self {
273
- Self::Sync(ref handle) => handle.read(buf),
274
- Self::Async(_) => {
275
- self.alertable_io_internal(c::ReadFileEx, buf.as_mut_ptr() as _, len)
276
- }
277
- }
242
+ self.alertable_io_internal(c::ReadFileEx, buf.as_mut_ptr() as _, len)
278
243
};
279
244
280
245
match result {
@@ -288,33 +253,28 @@ impl AnonPipe {
288
253
}
289
254
290
255
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
291
- io::default_read_vectored(|buf| self.read(buf), bufs)
256
+ self.inner.read_vectored( bufs)
292
257
}
293
258
294
259
#[inline]
295
260
pub fn is_read_vectored(&self) -> bool {
296
- false
261
+ self.inner.is_read_vectored()
297
262
}
298
263
299
264
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
300
265
unsafe {
301
266
let len = crate::cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD;
302
- match self {
303
- Self::Sync(ref handle) => handle.write(buf),
304
- Self::Async(_) => {
305
- self.alertable_io_internal(c::WriteFileEx, buf.as_ptr() as _, len)
306
- }
307
- }
267
+ self.alertable_io_internal(c::WriteFileEx, buf.as_ptr() as _, len)
308
268
}
309
269
}
310
270
311
271
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
312
- io::default_write_vectored(|buf| self.write(buf), bufs)
272
+ self.inner.write_vectored( bufs)
313
273
}
314
274
315
275
#[inline]
316
276
pub fn is_write_vectored(&self) -> bool {
317
- false
277
+ self.inner.is_write_vectored()
318
278
}
319
279
320
280
/// Synchronizes asynchronous reads or writes using our anonymous pipe.
@@ -386,7 +346,7 @@ impl AnonPipe {
386
346
387
347
// Asynchronous read of the pipe.
388
348
// If successful, `callback` will be called once it completes.
389
- 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);
390
350
if result == c::FALSE {
391
351
// We can return here because the call failed.
392
352
// After this we must not return until the I/O completes.
0 commit comments