Skip to content

Commit

Permalink
refactor: remove an unsafe and some boxing (denoland#4398)
Browse files Browse the repository at this point in the history
  • Loading branch information
95th committed Mar 16, 2020
1 parent 0d14a7b commit 8077ade
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 43 deletions.
26 changes: 12 additions & 14 deletions cli/http_util.rs
Expand Up @@ -195,7 +195,7 @@ impl AsyncRead for HttpBody {
let n = min(buf.len(), chunk.len() - inner.pos);
{
let rest = &chunk[inner.pos..];
buf[..n].clone_from_slice(&rest[..n]);
buf[..n].copy_from_slice(&rest[..n]);
}
inner.pos += n;
if inner.pos == chunk.len() {
Expand All @@ -208,31 +208,29 @@ impl AsyncRead for HttpBody {
assert_eq!(inner.pos, 0);
}

let chunk_future = &mut inner.response.chunk();
// Safety: `chunk_future` lives only for duration of this poll. So, it doesn't move.
let chunk_future = unsafe { Pin::new_unchecked(chunk_future) };
match chunk_future.poll(cx) {
Poll::Ready(Err(e)) => {
Poll::Ready(Err(io::Error::new(io::ErrorKind::Other, e)))
}
Poll::Ready(Ok(Some(chunk))) => {
let chunk_future = inner.response.chunk();
futures::pin_mut!(chunk_future);

let result = match futures::ready!(chunk_future.poll(cx)) {
Err(e) => Err(io::Error::new(io::ErrorKind::Other, e)),
Ok(Some(chunk)) => {
debug!(
"HttpBody Real Read buf {} chunk {} pos {}",
buf.len(),
chunk.len(),
inner.pos
);
let n = min(buf.len(), chunk.len());
buf[..n].clone_from_slice(&chunk[..n]);
buf[..n].copy_from_slice(&chunk[..n]);
if buf.len() < chunk.len() {
inner.pos = n;
inner.chunk = Some(chunk);
}
Poll::Ready(Ok(n))
Ok(n)
}
Poll::Ready(Ok(None)) => Poll::Ready(Ok(0)),
Poll::Pending => Poll::Pending,
}
Ok(None) => Ok(0),
};
result.into()
}
}

Expand Down
63 changes: 34 additions & 29 deletions cli/ops/io.rs
Expand Up @@ -156,6 +156,12 @@ pub enum StreamResource {
ChildStderr(tokio::process::ChildStderr),
}

trait UnpinAsyncRead: AsyncRead + Unpin {}
trait UnpinAsyncWrite: AsyncWrite + Unpin {}

impl<T: AsyncRead + Unpin> UnpinAsyncRead for T {}
impl<T: AsyncWrite + Unpin> UnpinAsyncWrite for T {}

/// `DenoAsyncRead` is the same as the `tokio_io::AsyncRead` trait
/// but uses an `OpError` error instead of `std::io:Error`
pub trait DenoAsyncRead {
Expand All @@ -173,19 +179,18 @@ impl DenoAsyncRead for StreamResource {
buf: &mut [u8],
) -> Poll<Result<usize, OpError>> {
use StreamResource::*;
let mut f: Pin<Box<dyn AsyncRead>> = match self {
FsFile(f, _) => Box::pin(f),
Stdin(f, _) => Box::pin(f),
TcpStream(f) => Box::pin(f),
ClientTlsStream(f) => Box::pin(f),
ServerTlsStream(f) => Box::pin(f),
ChildStdout(f) => Box::pin(f),
ChildStderr(f) => Box::pin(f),
HttpBody(f) => Box::pin(f),
let f: &mut dyn UnpinAsyncRead = match self {
FsFile(f, _) => f,
Stdin(f, _) => f,
TcpStream(f) => f,
ClientTlsStream(f) => f,
ServerTlsStream(f) => f,
ChildStdout(f) => f,
ChildStderr(f) => f,
HttpBody(f) => f,
_ => return Err(OpError::bad_resource_id()).into(),
};

let v = ready!(f.as_mut().poll_read(cx, buf))?;
let v = ready!(Pin::new(f).poll_read(cx, buf))?;
Ok(v).into()
}
}
Expand Down Expand Up @@ -252,35 +257,35 @@ impl DenoAsyncWrite for StreamResource {
buf: &[u8],
) -> Poll<Result<usize, OpError>> {
use StreamResource::*;
let mut f: Pin<Box<dyn AsyncWrite>> = match self {
FsFile(f, _) => Box::pin(f),
Stdout(f) => Box::pin(f),
Stderr(f) => Box::pin(f),
TcpStream(f) => Box::pin(f),
ClientTlsStream(f) => Box::pin(f),
ServerTlsStream(f) => Box::pin(f),
ChildStdin(f) => Box::pin(f),
let f: &mut dyn UnpinAsyncWrite = match self {
FsFile(f, _) => f,
Stdout(f) => f,
Stderr(f) => f,
TcpStream(f) => f,
ClientTlsStream(f) => f,
ServerTlsStream(f) => f,
ChildStdin(f) => f,
_ => return Err(OpError::bad_resource_id()).into(),
};

let v = ready!(f.as_mut().poll_write(cx, buf))?;
let v = ready!(Pin::new(f).poll_write(cx, buf))?;
Ok(v).into()
}

fn poll_flush(&mut self, cx: &mut Context) -> Poll<Result<(), OpError>> {
use StreamResource::*;
let mut f: Pin<Box<dyn AsyncWrite>> = match self {
FsFile(f, _) => Box::pin(f),
Stdout(f) => Box::pin(f),
Stderr(f) => Box::pin(f),
TcpStream(f) => Box::pin(f),
ClientTlsStream(f) => Box::pin(f),
ServerTlsStream(f) => Box::pin(f),
ChildStdin(f) => Box::pin(f),
let f: &mut dyn UnpinAsyncWrite = match self {
FsFile(f, _) => f,
Stdout(f) => f,
Stderr(f) => f,
TcpStream(f) => f,
ClientTlsStream(f) => f,
ServerTlsStream(f) => f,
ChildStdin(f) => f,
_ => return Err(OpError::bad_resource_id()).into(),
};

ready!(f.as_mut().poll_flush(cx))?;
ready!(Pin::new(f).poll_flush(cx))?;
Ok(()).into()
}

Expand Down

0 comments on commit 8077ade

Please sign in to comment.