Skip to content

Commit

Permalink
Use io::blocking instead of fs
Browse files Browse the repository at this point in the history
  • Loading branch information
ipetkov committed Jul 20, 2022
1 parent acbd97d commit d00e303
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 15 deletions.
3 changes: 2 additions & 1 deletion tokio/src/io/blocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ enum State<T> {
Busy(sys::Blocking<(io::Result<usize>, Buf, T)>),
}

cfg_io_std! {
cfg_io_blocking! {
impl<T> Blocking<T> {
#[cfg_attr(feature = "fs", allow(dead_code))]
pub(crate) fn new(inner: T) -> Blocking<T> {
Blocking {
inner: Some(inner),
Expand Down
67 changes: 53 additions & 14 deletions tokio/src/process/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
//! `RegisterWaitForSingleObject` and then wait on the other end of the oneshot
//! from then on out.

use crate::fs::File;
use crate::io::{blocking::Blocking, AsyncRead, AsyncWrite, ReadBuf};
use crate::process::kill::Kill;
use crate::process::SpawnedChild;
use crate::sync::oneshot;

use pin_project_lite::pin_project;
use std::fmt;
#[cfg(not(test))]
use std::fs::File as StdFile;
use std::future::Future;
use std::io;
Expand Down Expand Up @@ -168,28 +168,67 @@ unsafe extern "system" fn callback(ptr: PVOID, _timer_fired: BOOLEAN) {
let _ = complete.take().unwrap().send(());
}

pub(crate) type ChildStdio = File;
pin_project! {
#[derive(Debug)]
pub(crate) struct ChildStdio {
// Used for accessing the raw handle, even if the io version is busy
raw: StdFile,
// For doing I/O operations asynchronously
#[pin]
io: Blocking<StdFile>,
}
}

impl AsRawHandle for ChildStdio {
fn as_raw_handle(&self) -> RawHandle {
self.raw.as_raw_handle()
}
}

impl AsyncRead for ChildStdio {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut ReadBuf<'_>,
) -> Poll<io::Result<()>> {
self.project().io.poll_read(cx, buf)
}
}

impl AsyncWrite for ChildStdio {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<io::Result<usize>> {
self.project().io.poll_write(cx, buf)
}

fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.project().io.poll_flush(cx)
}

fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.project().io.poll_shutdown(cx)
}
}

#[cfg(not(test))]
pub(super) fn stdio<T>(io: T) -> io::Result<ChildStdio>
where
T: IntoRawHandle,
{
use std::os::windows::prelude::FromRawHandle;

let std_file = unsafe { StdFile::from_raw_handle(io.into_raw_handle()) };
Ok(File::from(std_file))
let raw = unsafe { StdFile::from_raw_handle(io.into_raw_handle()) };
let io = Blocking::new(duplicate_handle(&raw)?);
Ok(ChildStdio { raw, io })
}

#[cfg(test)]
pub(super) fn stdio<T>(_io: T) -> io::Result<ChildStdio>
where
T: IntoRawHandle,
{
unimplemented!()
pub(crate) fn convert_to_stdio(io: ChildStdio) -> io::Result<Stdio> {
Ok(Stdio::from(io.raw))
}

pub(crate) fn convert_to_stdio(io: ChildStdio) -> io::Result<Stdio> {
fn duplicate_handle<T: AsRawHandle>(io: &T) -> io::Result<StdFile> {
use std::os::windows::prelude::FromRawHandle;

unsafe {
Expand All @@ -210,6 +249,6 @@ pub(crate) fn convert_to_stdio(io: ChildStdio) -> io::Result<Stdio> {
return Err(io::Error::last_os_error());
}

Ok(Stdio::from_raw_handle(dup_handle))
Ok(StdFile::from_raw_handle(dup_handle))
}
}

0 comments on commit d00e303

Please sign in to comment.