Unit tests pass
Fixed a nasty deadlock in reqnot
This commit is contained in:
@@ -27,7 +27,6 @@ pub fn pipe(size: usize) -> (Writer, Reader) {
|
||||
size,
|
||||
mut read_waker,
|
||||
mut write_waker,
|
||||
mut flush_waker,
|
||||
reader_dropped,
|
||||
writer_dropped,
|
||||
// irrelevant if correctly dropped
|
||||
@@ -42,7 +41,6 @@ pub fn pipe(size: usize) -> (Writer, Reader) {
|
||||
}
|
||||
read_waker.drop();
|
||||
write_waker.drop();
|
||||
flush_waker.drop();
|
||||
unsafe { dealloc(start, pipe_layout(size)) }
|
||||
}
|
||||
let state = Box::into_raw(Box::new(AsyncRingbuffer {
|
||||
@@ -53,7 +51,6 @@ pub fn pipe(size: usize) -> (Writer, Reader) {
|
||||
write_idx: 0,
|
||||
read_waker: Trigger::empty(),
|
||||
write_waker: Trigger::empty(),
|
||||
flush_waker: Trigger::empty(),
|
||||
reader_dropped: false,
|
||||
writer_dropped: false,
|
||||
drop,
|
||||
@@ -110,21 +107,22 @@ struct AsyncRingbuffer {
|
||||
write_idx: usize,
|
||||
read_waker: Trigger,
|
||||
write_waker: Trigger,
|
||||
flush_waker: Trigger,
|
||||
reader_dropped: bool,
|
||||
writer_dropped: bool,
|
||||
drop: extern "C" fn(*const ()),
|
||||
}
|
||||
impl AsyncRingbuffer {
|
||||
fn wake_reader(&mut self) { self.read_waker.invoke() }
|
||||
fn wake_writer(&mut self) { self.write_waker.invoke() }
|
||||
fn drop_writer(&mut self) {
|
||||
self.read_waker.invoke();
|
||||
self.wake_reader();
|
||||
self.writer_dropped = true;
|
||||
if self.reader_dropped {
|
||||
(self.drop)(self.state)
|
||||
}
|
||||
}
|
||||
fn drop_reader(&mut self) {
|
||||
self.write_waker.invoke();
|
||||
self.wake_writer();
|
||||
self.reader_dropped = true;
|
||||
if self.writer_dropped {
|
||||
(self.drop)(self.state)
|
||||
@@ -134,25 +132,14 @@ impl AsyncRingbuffer {
|
||||
if self.reader_dropped {
|
||||
return Poll::Ready(Err(broken_pipe_error()));
|
||||
}
|
||||
self.read_waker.invoke();
|
||||
self.write_waker.drop();
|
||||
self.write_waker = Trigger::new(waker.clone());
|
||||
Poll::Pending
|
||||
}
|
||||
fn flush_wait<T>(&mut self, waker: &Waker) -> Poll<io::Result<T>> {
|
||||
if self.reader_dropped {
|
||||
return Poll::Ready(Err(broken_pipe_error()));
|
||||
}
|
||||
self.read_waker.invoke();
|
||||
self.flush_waker.drop();
|
||||
self.flush_waker = Trigger::new(waker.clone());
|
||||
Poll::Pending
|
||||
}
|
||||
fn reader_wait(&mut self, waker: &Waker) -> Poll<io::Result<usize>> {
|
||||
if self.writer_dropped {
|
||||
return Poll::Ready(Err(broken_pipe_error()));
|
||||
}
|
||||
self.write_waker.invoke();
|
||||
self.read_waker.drop();
|
||||
self.read_waker = Trigger::new(waker.clone());
|
||||
Poll::Pending
|
||||
@@ -234,7 +221,7 @@ impl Writer {
|
||||
return Err(SyncWriteError::BufferFull);
|
||||
}
|
||||
state.wrapping_write_unchecked(data);
|
||||
state.write_waker.invoke();
|
||||
state.wake_reader();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -255,7 +242,7 @@ impl AsyncWrite for Writer {
|
||||
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||
unsafe {
|
||||
let data = self.as_mut().get_state()?;
|
||||
if data.is_empty() { Poll::Ready(Ok(())) } else { data.flush_wait(cx.waker()) }
|
||||
if data.is_empty() { Poll::Ready(Ok(())) } else { data.writer_wait(cx.waker()) }
|
||||
}
|
||||
}
|
||||
fn poll_write(
|
||||
@@ -263,12 +250,15 @@ impl AsyncWrite for Writer {
|
||||
cx: &mut Context<'_>,
|
||||
buf: &[u8],
|
||||
) -> Poll<io::Result<usize>> {
|
||||
if buf.is_empty() {
|
||||
return Poll::Ready(Ok(0));
|
||||
}
|
||||
unsafe {
|
||||
let data = self.as_mut().get_state()?;
|
||||
if !buf.is_empty() && data.is_empty() {
|
||||
data.read_waker.invoke();
|
||||
if data.is_empty() {
|
||||
data.wake_reader();
|
||||
}
|
||||
if !buf.is_empty() && data.is_full() {
|
||||
if data.is_full() {
|
||||
data.writer_wait(cx.waker())
|
||||
} else {
|
||||
Poll::Ready(Ok(data.wrapping_write_unchecked(buf)))
|
||||
@@ -300,7 +290,7 @@ impl AsyncRead for Reader {
|
||||
let data = self.0.as_mut().expect("Cannot be null");
|
||||
let AsyncRingbuffer { read_idx, write_idx, size, .. } = *data;
|
||||
if !buf.is_empty() && data.is_full() {
|
||||
data.write_waker.invoke();
|
||||
data.wake_writer();
|
||||
}
|
||||
let poll = if !buf.is_empty() && data.is_empty() {
|
||||
// Nothing to read, waiting...
|
||||
@@ -322,8 +312,8 @@ impl AsyncRead for Reader {
|
||||
data.non_wrapping_read_unchecked(&mut start[0..start_count]);
|
||||
Poll::Ready(Ok(end.len() + start_count))
|
||||
};
|
||||
if !buf.is_empty() && data.is_empty() {
|
||||
data.flush_waker.invoke();
|
||||
if data.is_empty() {
|
||||
data.wake_writer();
|
||||
}
|
||||
poll
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user