1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-11 16:42:21 -05:00

refactor: remove an unsafe and some boxing (#4398)

This commit is contained in:
Gurwinder Singh 2020-03-16 17:46:31 +00:00 committed by GitHub
parent 0d14a7bd53
commit 8077ade741
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 43 deletions

View file

@ -195,7 +195,7 @@ impl AsyncRead for HttpBody {
let n = min(buf.len(), chunk.len() - inner.pos); let n = min(buf.len(), chunk.len() - inner.pos);
{ {
let rest = &chunk[inner.pos..]; let rest = &chunk[inner.pos..];
buf[..n].clone_from_slice(&rest[..n]); buf[..n].copy_from_slice(&rest[..n]);
} }
inner.pos += n; inner.pos += n;
if inner.pos == chunk.len() { if inner.pos == chunk.len() {
@ -208,14 +208,12 @@ impl AsyncRead for HttpBody {
assert_eq!(inner.pos, 0); assert_eq!(inner.pos, 0);
} }
let chunk_future = &mut inner.response.chunk(); let chunk_future = inner.response.chunk();
// Safety: `chunk_future` lives only for duration of this poll. So, it doesn't move. futures::pin_mut!(chunk_future);
let chunk_future = unsafe { Pin::new_unchecked(chunk_future) };
match chunk_future.poll(cx) { let result = match futures::ready!(chunk_future.poll(cx)) {
Poll::Ready(Err(e)) => { Err(e) => Err(io::Error::new(io::ErrorKind::Other, e)),
Poll::Ready(Err(io::Error::new(io::ErrorKind::Other, e))) Ok(Some(chunk)) => {
}
Poll::Ready(Ok(Some(chunk))) => {
debug!( debug!(
"HttpBody Real Read buf {} chunk {} pos {}", "HttpBody Real Read buf {} chunk {} pos {}",
buf.len(), buf.len(),
@ -223,16 +221,16 @@ impl AsyncRead for HttpBody {
inner.pos inner.pos
); );
let n = min(buf.len(), chunk.len()); 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() { if buf.len() < chunk.len() {
inner.pos = n; inner.pos = n;
inner.chunk = Some(chunk); inner.chunk = Some(chunk);
} }
Poll::Ready(Ok(n)) Ok(n)
} }
Poll::Ready(Ok(None)) => Poll::Ready(Ok(0)), Ok(None) => Ok(0),
Poll::Pending => Poll::Pending, };
} result.into()
} }
} }

View file

@ -156,6 +156,12 @@ pub enum StreamResource {
ChildStderr(tokio::process::ChildStderr), 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 /// `DenoAsyncRead` is the same as the `tokio_io::AsyncRead` trait
/// but uses an `OpError` error instead of `std::io:Error` /// but uses an `OpError` error instead of `std::io:Error`
pub trait DenoAsyncRead { pub trait DenoAsyncRead {
@ -173,19 +179,18 @@ impl DenoAsyncRead for StreamResource {
buf: &mut [u8], buf: &mut [u8],
) -> Poll<Result<usize, OpError>> { ) -> Poll<Result<usize, OpError>> {
use StreamResource::*; use StreamResource::*;
let mut f: Pin<Box<dyn AsyncRead>> = match self { let f: &mut dyn UnpinAsyncRead = match self {
FsFile(f, _) => Box::pin(f), FsFile(f, _) => f,
Stdin(f, _) => Box::pin(f), Stdin(f, _) => f,
TcpStream(f) => Box::pin(f), TcpStream(f) => f,
ClientTlsStream(f) => Box::pin(f), ClientTlsStream(f) => f,
ServerTlsStream(f) => Box::pin(f), ServerTlsStream(f) => f,
ChildStdout(f) => Box::pin(f), ChildStdout(f) => f,
ChildStderr(f) => Box::pin(f), ChildStderr(f) => f,
HttpBody(f) => Box::pin(f), HttpBody(f) => f,
_ => return Err(OpError::bad_resource_id()).into(), _ => return Err(OpError::bad_resource_id()).into(),
}; };
let v = ready!(Pin::new(f).poll_read(cx, buf))?;
let v = ready!(f.as_mut().poll_read(cx, buf))?;
Ok(v).into() Ok(v).into()
} }
} }
@ -252,35 +257,35 @@ impl DenoAsyncWrite for StreamResource {
buf: &[u8], buf: &[u8],
) -> Poll<Result<usize, OpError>> { ) -> Poll<Result<usize, OpError>> {
use StreamResource::*; use StreamResource::*;
let mut f: Pin<Box<dyn AsyncWrite>> = match self { let f: &mut dyn UnpinAsyncWrite = match self {
FsFile(f, _) => Box::pin(f), FsFile(f, _) => f,
Stdout(f) => Box::pin(f), Stdout(f) => f,
Stderr(f) => Box::pin(f), Stderr(f) => f,
TcpStream(f) => Box::pin(f), TcpStream(f) => f,
ClientTlsStream(f) => Box::pin(f), ClientTlsStream(f) => f,
ServerTlsStream(f) => Box::pin(f), ServerTlsStream(f) => f,
ChildStdin(f) => Box::pin(f), ChildStdin(f) => f,
_ => return Err(OpError::bad_resource_id()).into(), _ => 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() Ok(v).into()
} }
fn poll_flush(&mut self, cx: &mut Context) -> Poll<Result<(), OpError>> { fn poll_flush(&mut self, cx: &mut Context) -> Poll<Result<(), OpError>> {
use StreamResource::*; use StreamResource::*;
let mut f: Pin<Box<dyn AsyncWrite>> = match self { let f: &mut dyn UnpinAsyncWrite = match self {
FsFile(f, _) => Box::pin(f), FsFile(f, _) => f,
Stdout(f) => Box::pin(f), Stdout(f) => f,
Stderr(f) => Box::pin(f), Stderr(f) => f,
TcpStream(f) => Box::pin(f), TcpStream(f) => f,
ClientTlsStream(f) => Box::pin(f), ClientTlsStream(f) => f,
ServerTlsStream(f) => Box::pin(f), ServerTlsStream(f) => f,
ChildStdin(f) => Box::pin(f), ChildStdin(f) => f,
_ => return Err(OpError::bad_resource_id()).into(), _ => return Err(OpError::bad_resource_id()).into(),
}; };
ready!(f.as_mut().poll_flush(cx))?; ready!(Pin::new(f).poll_flush(cx))?;
Ok(()).into() Ok(()).into()
} }