mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-24 00:00:11 +02:00
Clean up the pipe-hup test slightly
This commit is contained in:
+1
-1
@@ -20,4 +20,4 @@ slab = "0.3"
|
||||
|
||||
[dev-dependencies]
|
||||
env_logger = { version = "0.3", default-features = false }
|
||||
nix = "0.7"
|
||||
libc = "0.2"
|
||||
|
||||
+32
-63
@@ -2,20 +2,18 @@
|
||||
|
||||
extern crate env_logger;
|
||||
extern crate futures;
|
||||
extern crate nix;
|
||||
extern crate libc;
|
||||
extern crate mio;
|
||||
extern crate tokio_core;
|
||||
|
||||
use std::io;
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
use std::time::Duration;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Write};
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use mio::{Evented, PollOpt, Ready, Token};
|
||||
use mio::unix::EventedFd;
|
||||
use nix::fcntl::{fcntl, O_NONBLOCK};
|
||||
use nix::fcntl::FcntlArg::F_SETFL;
|
||||
use nix::unistd::{close, pipe, read, write};
|
||||
|
||||
use tokio_core::io::read_to_end;
|
||||
use tokio_core::reactor::{Core, PollEvented};
|
||||
@@ -27,51 +25,25 @@ macro_rules! t {
|
||||
})
|
||||
}
|
||||
|
||||
fn set_nonblock(s: &AsRawFd) -> io::Result<()> {
|
||||
fcntl(s.as_raw_fd(), F_SETFL(O_NONBLOCK)).map_err(from_nix_error)
|
||||
.map(|_| ())
|
||||
}
|
||||
struct MyFile(File);
|
||||
|
||||
fn from_nix_error(err: nix::Error) -> io::Error {
|
||||
io::Error::from_raw_os_error(err.errno() as i32)
|
||||
}
|
||||
|
||||
struct PipeSource(RawFd);
|
||||
|
||||
impl io::Read for PipeSource {
|
||||
fn read(&mut self, bytes: &mut [u8]) -> io::Result<usize> {
|
||||
read(self.as_raw_fd(), bytes).map_err(from_nix_error)
|
||||
impl MyFile {
|
||||
fn new(file: File) -> MyFile {
|
||||
unsafe {
|
||||
let r = libc::fcntl(file.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK);
|
||||
assert!(r != -1, "fcntl error: {}", io::Error::last_os_error());
|
||||
}
|
||||
MyFile(file)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StdStream<T> {
|
||||
io: PollEvented<RawFdWrap<T>>,
|
||||
}
|
||||
|
||||
impl<T> io::Read for StdStream<T> where T: io::Read {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.io.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
struct RawFdWrap<T>(T);
|
||||
|
||||
impl<T> RawFdWrap<T> {
|
||||
fn new(fd: T) -> io::Result<Self>
|
||||
where T: AsRawFd {
|
||||
|
||||
try!(set_nonblock(&fd));
|
||||
Ok(RawFdWrap(fd))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> io::Read for RawFdWrap<T> where T: io::Read {
|
||||
impl io::Read for MyFile {
|
||||
fn read(&mut self, bytes: &mut [u8]) -> io::Result<usize> {
|
||||
self.0.read(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Evented for RawFdWrap<T> where T: AsRawFd {
|
||||
impl Evented for MyFile {
|
||||
fn register(&self, poll: &mio::Poll, token: Token, interest: Ready, opts: PollOpt)
|
||||
-> io::Result<()> {
|
||||
EventedFd(&self.0.as_raw_fd()).register(poll, token, interest | Ready::hup(), opts)
|
||||
@@ -85,31 +57,28 @@ impl<T> Evented for RawFdWrap<T> where T: AsRawFd {
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawFd for PipeSource {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hup() {
|
||||
drop(env_logger::init());
|
||||
|
||||
let mut l = t!(Core::new());
|
||||
let (source, sink) = pipe().unwrap();
|
||||
let t = thread::spawn(move || {
|
||||
write(sink, b"Hello!\n").unwrap();
|
||||
write(sink, b"Good bye!\n").unwrap();
|
||||
thread::sleep(Duration::from_millis(100));
|
||||
close(sink).unwrap();
|
||||
});
|
||||
unsafe {
|
||||
let mut pipes = [0; 2];
|
||||
assert!(libc::pipe(pipes.as_mut_ptr()) != -1,
|
||||
"pipe error: {}", io::Error::last_os_error());
|
||||
let read = File::from_raw_fd(pipes[0]);
|
||||
let mut write = File::from_raw_fd(pipes[1]);
|
||||
let t = thread::spawn(move || {
|
||||
write.write_all(b"Hello!\n").unwrap();
|
||||
write.write_all(b"Good bye!\n").unwrap();
|
||||
thread::sleep(Duration::from_millis(100));
|
||||
});
|
||||
|
||||
let source = StdStream {
|
||||
io: PollEvented::new(RawFdWrap::new(PipeSource(source)).unwrap(), &l.handle()).unwrap()
|
||||
};
|
||||
let source = PollEvented::new(MyFile::new(read), &l.handle()).unwrap();
|
||||
|
||||
let reader = read_to_end(source, Vec::new());
|
||||
let (_, content) = t!(l.run(reader));
|
||||
assert_eq!(&b"Hello!\nGood bye!\n"[..], &content[..]);
|
||||
t.join().unwrap();
|
||||
let reader = read_to_end(source, Vec::new());
|
||||
let (_, content) = t!(l.run(reader));
|
||||
assert_eq!(&b"Hello!\nGood bye!\n"[..], &content[..]);
|
||||
t.join().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user