mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-07 00:00:08 +02:00
Re-work I/O
* Auto-register interest whenever we see WouldBlock
* Remove implementations of `Stream<Item=Ready>`, no longer needed
* Add explicit `poll_{read,write}` methods, if needed
* Remove all I/O streams, libstd ones suffice
* Update all I/O futures
This commit is contained in:
+46
-25
@@ -1,8 +1,7 @@
|
||||
use std::io;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use futures::stream::Stream;
|
||||
use futures::{Future, Task, Poll};
|
||||
use futures_io::{Ready};
|
||||
use futures::{Future, Poll};
|
||||
|
||||
use event_loop::{IoSource, LoopHandle, AddSource};
|
||||
|
||||
@@ -23,6 +22,7 @@ pub struct ReadinessStream {
|
||||
io_token: usize,
|
||||
loop_handle: LoopHandle,
|
||||
source: IoSource,
|
||||
readiness: AtomicUsize,
|
||||
}
|
||||
|
||||
pub struct ReadinessStreamNew {
|
||||
@@ -45,43 +45,64 @@ impl ReadinessStream {
|
||||
handle: Some(loop_handle),
|
||||
}
|
||||
}
|
||||
|
||||
/// Tests to see if this source is ready to be read from or not.
|
||||
pub fn poll_read(&self) -> Poll<(), io::Error> {
|
||||
if self.readiness.load(Ordering::SeqCst) & 1 != 0 {
|
||||
return Poll::Ok(())
|
||||
}
|
||||
self.readiness.fetch_or(self.source.take_readiness(), Ordering::SeqCst);
|
||||
if self.readiness.load(Ordering::SeqCst) & 1 != 0 {
|
||||
Poll::Ok(())
|
||||
} else {
|
||||
self.loop_handle.schedule_read(self.io_token);
|
||||
Poll::NotReady
|
||||
}
|
||||
}
|
||||
|
||||
/// Tests to see if this source is ready to be written to or not.
|
||||
pub fn poll_write(&self) -> Poll<(), io::Error> {
|
||||
if self.readiness.load(Ordering::SeqCst) & 2 != 0 {
|
||||
return Poll::Ok(())
|
||||
}
|
||||
self.readiness.fetch_or(self.source.take_readiness(), Ordering::SeqCst);
|
||||
if self.readiness.load(Ordering::SeqCst) & 2 != 0 {
|
||||
Poll::Ok(())
|
||||
} else {
|
||||
self.loop_handle.schedule_write(self.io_token);
|
||||
Poll::NotReady
|
||||
}
|
||||
}
|
||||
|
||||
/// Tests to see if this source is ready to be read from or not.
|
||||
pub fn need_read(&self) {
|
||||
self.readiness.fetch_and(!1, Ordering::SeqCst);
|
||||
self.loop_handle.schedule_read(self.io_token);
|
||||
}
|
||||
|
||||
/// Tests to see if this source is ready to be written to or not.
|
||||
pub fn need_write(&self) {
|
||||
self.readiness.fetch_and(!2, Ordering::SeqCst);
|
||||
self.loop_handle.schedule_write(self.io_token);
|
||||
}
|
||||
}
|
||||
|
||||
impl Future for ReadinessStreamNew {
|
||||
type Item = ReadinessStream;
|
||||
type Error = io::Error;
|
||||
|
||||
fn poll(&mut self, task: &mut Task) -> Poll<ReadinessStream, io::Error> {
|
||||
self.inner.poll(task).map(|token| {
|
||||
fn poll(&mut self) -> Poll<ReadinessStream, io::Error> {
|
||||
self.inner.poll().map(|token| {
|
||||
ReadinessStream {
|
||||
io_token: token,
|
||||
source: self.source.take().unwrap(),
|
||||
loop_handle: self.handle.take().unwrap(),
|
||||
readiness: AtomicUsize::new(0),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Stream for ReadinessStream {
|
||||
type Item = Ready;
|
||||
type Error = io::Error;
|
||||
|
||||
fn poll(&mut self, task: &mut Task) -> Poll<Option<Ready>, io::Error> {
|
||||
match self.source.take_readiness() {
|
||||
None => {
|
||||
self.loop_handle.schedule(self.io_token, task);
|
||||
Poll::NotReady
|
||||
}
|
||||
Some(r) => {
|
||||
if !r.is_read() || !r.is_write() {
|
||||
self.loop_handle.schedule(self.io_token, task);
|
||||
}
|
||||
Poll::Ok(Some(r))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ReadinessStream {
|
||||
fn drop(&mut self) {
|
||||
self.loop_handle.drop_source(self.io_token)
|
||||
|
||||
Reference in New Issue
Block a user