Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions library/std/src/sys/process/windows/child_pipe.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
use crate::ops::Neg;
use crate::os::windows::prelude::*;
use crate::sync::atomic::Atomic;
use crate::sync::atomic::Ordering::Relaxed;
use crate::sys::handle::Handle;
use crate::sys::{FromInner, IntoInner, api, c};
use crate::{mem, ptr};
Expand Down Expand Up @@ -70,10 +72,15 @@ pub(super) fn child_pipe(ours_readable: bool, their_handle_inheritable: bool) ->
let mut object_attributes = c::OBJECT_ATTRIBUTES::default();
object_attributes.Length = size_of::<c::OBJECT_ATTRIBUTES>() as u32;

// Open a handle to the pipe filesystem (`\??\PIPE\`).
// This will be used when creating a new annon pipe.
let pipe_fs = {
let path = api::unicode_str!(r"\??\PIPE\");
// Open a handle to the pipe filesystem (`\Device\NamedPipe\`) and cache it.
// This will be used when creating a new anonymous pipe.
static PIPE_FS: Atomic<c::HANDLE> = Atomic::<c::HANDLE>::new(ptr::null_mut());
let pipe_fs = if let handle = PIPE_FS.load(Relaxed)
&& !handle.is_null()
{
handle
} else {
let path = api::unicode_str!(r"\Device\NamedPipe\");
object_attributes.ObjectName = path.as_ptr();
let mut pipe_fs = ptr::null_mut();
let status = c::NtOpenFile(
Expand All @@ -85,7 +92,13 @@ pub(super) fn child_pipe(ours_readable: bool, their_handle_inheritable: bool) ->
c::FILE_SYNCHRONOUS_IO_NONALERT, // synchronous access
);
if c::nt_success(status) {
Handle::from_raw_handle(pipe_fs)
match PIPE_FS.compare_exchange(ptr::null_mut(), pipe_fs, Relaxed, Relaxed) {
Ok(_) => pipe_fs,
Err(existing) => {
c::CloseHandle(pipe_fs);
existing
}
}
} else {
return Err(io::Error::from_raw_os_error(c::RtlNtStatusToDosError(status) as i32));
}
Expand All @@ -104,7 +117,7 @@ pub(super) fn child_pipe(ours_readable: bool, their_handle_inheritable: bool) ->
let ours = {
// Use the pipe filesystem as the root directory.
// With no name provided, an anonymous pipe will be created.
object_attributes.RootDirectory = pipe_fs.as_raw_handle();
object_attributes.RootDirectory = pipe_fs;

// A negative timeout value is a relative time (rather than an absolute time).
// The time is given in 100's of nanoseconds so this is 50 milliseconds.
Expand Down
Loading