Skip to content

Commit 7925656

Browse files
Revert "Windows: Make stdin pipes synchronous"
This reverts commit 949b978.
1 parent fba04fd commit 7925656

File tree

3 files changed

+31
-85
lines changed

3 files changed

+31
-85
lines changed

library/std/src/sys/windows/c.rs

-6
Original file line numberDiff line numberDiff line change
@@ -1022,12 +1022,6 @@ extern "system" {
10221022
bWaitAll: BOOL,
10231023
dwMilliseconds: DWORD,
10241024
) -> DWORD;
1025-
pub fn CreatePipe(
1026-
hReadPipe: *mut HANDLE,
1027-
hWritePipe: *mut HANDLE,
1028-
lpPipeAttributes: *const SECURITY_ATTRIBUTES,
1029-
nSize: DWORD,
1030-
) -> BOOL;
10311025
pub fn CreateNamedPipeW(
10321026
lpName: LPCWSTR,
10331027
dwOpenMode: DWORD,

library/std/src/sys/windows/pipe.rs

+25-65
Original file line numberDiff line numberDiff line change
@@ -18,56 +18,20 @@ use crate::sys_common::IntoInner;
1818
// Anonymous pipes
1919
////////////////////////////////////////////////////////////////////////////////
2020

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,
2723
}
2824

2925
impl IntoInner<Handle> for AnonPipe {
3026
fn into_inner(self) -> Handle {
31-
match self {
32-
Self::Sync(handle) => handle,
33-
Self::Async(handle) => handle,
34-
}
27+
self.inner
3528
}
3629
}
3730

3831
pub struct Pipes {
3932
pub ours: AnonPipe,
4033
pub theirs: AnonPipe,
4134
}
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-
}
7135

7236
/// Although this looks similar to `anon_pipe` in the Unix module it's actually
7337
/// subtly different. Here we'll return two pipes in the `Pipes` return value,
@@ -89,6 +53,9 @@ impl Pipes {
8953
/// with `OVERLAPPED` instances, but also works out ok if it's only ever used
9054
/// once at a time (which we do indeed guarantee).
9155
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+
9259
// Note that we specifically do *not* use `CreatePipe` here because
9360
// unfortunately the anonymous pipes returned do not support overlapped
9461
// 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
189156
};
190157
opts.security_attributes(&mut sa);
191158
let theirs = File::open(Path::new(&name), &opts)?;
192-
let theirs = AnonPipe::Sync(theirs.into_inner());
159+
let theirs = AnonPipe { inner: theirs.into_inner() };
193160

194-
Ok(Pipes { ours: AnonPipe::Async(ours), theirs })
161+
Ok(Pipes {
162+
ours: AnonPipe { inner: ours },
163+
theirs: AnonPipe { inner: theirs.into_inner() },
164+
})
195165
}
196166
}
197167

@@ -201,12 +171,12 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
201171
/// This is achieved by creating a new set of pipes and spawning a thread that
202172
/// relays messages between the source and the synchronous pipe.
203173
pub fn spawn_pipe_relay(
204-
source: &Handle,
174+
source: &AnonPipe,
205175
ours_readable: bool,
206176
their_handle_inheritable: bool,
207177
) -> io::Result<AnonPipe> {
208178
// 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()?;
210180

211181
// create a new pair of anon pipes.
212182
let Pipes { theirs, ours } = anon_pipe(ours_readable, their_handle_inheritable)?;
@@ -257,24 +227,19 @@ type AlertableIoFn = unsafe extern "system" fn(
257227

258228
impl AnonPipe {
259229
pub fn handle(&self) -> &Handle {
260-
match self {
261-
Self::Async(ref handle) => handle,
262-
Self::Sync(ref handle) => handle,
263-
}
230+
&self.inner
264231
}
265232
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 })
267237
}
268238

269239
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
270240
let result = unsafe {
271241
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)
278243
};
279244

280245
match result {
@@ -288,33 +253,28 @@ impl AnonPipe {
288253
}
289254

290255
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)
292257
}
293258

294259
#[inline]
295260
pub fn is_read_vectored(&self) -> bool {
296-
false
261+
self.inner.is_read_vectored()
297262
}
298263

299264
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
300265
unsafe {
301266
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)
308268
}
309269
}
310270

311271
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)
313273
}
314274

315275
#[inline]
316276
pub fn is_write_vectored(&self) -> bool {
317-
false
277+
self.inner.is_write_vectored()
318278
}
319279

320280
/// Synchronizes asynchronous reads or writes using our anonymous pipe.
@@ -386,7 +346,7 @@ impl AnonPipe {
386346

387347
// Asynchronous read of the pipe.
388348
// 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);
390350
if result == c::FALSE {
391351
// We can return here because the call failed.
392352
// After this we must not return until the I/O completes.

library/std/src/sys/windows/process.rs

+6-14
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::sys::cvt;
2323
use crate::sys::fs::{File, OpenOptions};
2424
use crate::sys::handle::Handle;
2525
use crate::sys::path;
26-
use crate::sys::pipe::{self, AnonPipe, Pipes};
26+
use crate::sys::pipe::{self, AnonPipe};
2727
use crate::sys::stdio;
2828
use crate::sys_common::mutex::StaticMutex;
2929
use crate::sys_common::process::{CommandEnv, CommandEnvs};
@@ -172,7 +172,7 @@ pub enum Stdio {
172172
Inherit,
173173
Null,
174174
MakePipe,
175-
AsyncPipe(Handle),
175+
Pipe(AnonPipe),
176176
Handle(Handle),
177177
}
178178

@@ -527,18 +527,13 @@ impl Stdio {
527527
},
528528

529529
Stdio::MakePipe => {
530-
// If stdin then make synchronous
531-
let pipes = if stdio_id == c::STD_INPUT_HANDLE {
532-
Pipes::new_synchronous(false, true)?
533-
} else {
534-
pipe::anon_pipe(true, true)?
535-
};
530+
let ours_readable = stdio_id != c::STD_INPUT_HANDLE;
531+
let pipes = pipe::anon_pipe(ours_readable, true)?;
536532
*pipe = Some(pipes.ours);
537533
Ok(pipes.theirs.into_handle())
538534
}
539535

540-
Stdio::AsyncPipe(ref source) => {
541-
// We need to synchronize asynchronous pipes by using a pipe relay.
536+
Stdio::Pipe(ref source) => {
542537
let ours_readable = stdio_id != c::STD_INPUT_HANDLE;
543538
pipe::spawn_pipe_relay(source, ours_readable, true).map(AnonPipe::into_handle)
544539
}
@@ -567,10 +562,7 @@ impl Stdio {
567562

568563
impl From<AnonPipe> for Stdio {
569564
fn from(pipe: AnonPipe) -> Stdio {
570-
match pipe {
571-
AnonPipe::Sync(handle) => Stdio::Handle(handle),
572-
AnonPipe::Async(handle) => Stdio::AsyncPipe(handle),
573-
}
565+
Stdio::Pipe(pipe)
574566
}
575567
}
576568

0 commit comments

Comments
 (0)