From 8a54eadae0ef2f1762dbbb8a733f6916371a2a66 Mon Sep 17 00:00:00 2001 From: jD91mZM2 Date: Sat, 2 Jun 2018 16:34:47 +0200 Subject: [PATCH] Fix events & more event tests --- examples/event.rs | 128 ++++++++++++++++++++++++++++++++++++++++++++++ examples/main.rs | 84 ------------------------------ src/scheme.rs | 8 +-- 3 files changed, 133 insertions(+), 87 deletions(-) create mode 100644 examples/event.rs diff --git a/examples/event.rs b/examples/event.rs new file mode 100644 index 0000000000..a0aa4f0d25 --- /dev/null +++ b/examples/event.rs @@ -0,0 +1,128 @@ +extern crate syscall; + +use std::{ + fs::File, + io::{self, prelude::*}, + os::unix::io::{AsRawFd, FromRawFd} +}; + +fn from_syscall_error(error: syscall::Error) -> io::Error { + io::Error::from_raw_os_error(error.errno as i32) +} + +fn main() -> io::Result<()> { + let server = File::create("chan:hello_world")?; + + println!("Testing events..."); + + syscall::fcntl(server.as_raw_fd(), syscall::F_SETFL, syscall::O_NONBLOCK) + .map_err(from_syscall_error)?; + + let mut event_file = File::open("event:")?; + let mut time_file = File::open(format!("time:{}", syscall::CLOCK_MONOTONIC))?; + + let mut time = syscall::TimeSpec::default(); + time_file.read(&mut time)?; + time.tv_sec += 1; + time_file.write(&time)?; + time.tv_sec += 2; + time_file.write(&time)?; + time.tv_sec += 2; + time_file.write(&time)?; + + const TOKEN_TIMER: usize = 0; + const TOKEN_STREAM: usize = 1; + const TOKEN_SERVER: usize = 2; + const TOKEN_CLIENT: usize = 3; + + event_file.write(&syscall::Event { + id: time_file.as_raw_fd(), + flags: syscall::EVENT_READ, + data: TOKEN_TIMER + })?; + event_file.write(&syscall::Event { + id: server.as_raw_fd(), + flags: syscall::EVENT_WRITE | syscall::EVENT_READ, + data: TOKEN_SERVER + })?; + + let mut event = syscall::Event::default(); + + event_file.read(&mut event)?; + assert_eq!(event.data, TOKEN_TIMER); + assert_eq!(event.flags, syscall::EVENT_READ); + println!("-> Timed out"); + + let mut client = File::open("chan:hello_world")?; + event_file.write(&syscall::Event { + id: client.as_raw_fd(), + flags: syscall::EVENT_WRITE | syscall::EVENT_READ, + data: TOKEN_CLIENT + })?; + + event_file.read(&mut event)?; + assert_eq!(event.data, TOKEN_SERVER); + assert_eq!(event.flags, syscall::EVENT_WRITE); + println!("-> Accept event"); + + let dup = syscall::dup(server.as_raw_fd(), b"listen").map_err(from_syscall_error)?; + let mut dup = unsafe { File::from_raw_fd(dup) }; + + event_file.read(&mut event)?; + assert_eq!(event.data, TOKEN_CLIENT); + assert_eq!(event.flags, syscall::EVENT_WRITE); + println!("-> Writable event"); + + event_file.write(&syscall::Event { + id: dup.as_raw_fd(), + flags: syscall::EVENT_READ | syscall::EVENT_WRITE, + data: TOKEN_STREAM + })?; + + event_file.read(&mut event)?; + assert_eq!(event.data, TOKEN_STREAM); + assert_eq!(event.flags, syscall::EVENT_WRITE); + println!("-> Writable event"); + + event_file.read(&mut event)?; + assert_eq!(event.data, TOKEN_TIMER); + assert_eq!(event.flags, syscall::EVENT_READ); + println!("-> Timed out"); + + client.write(b"a")?; + + let mut buf = [0; 5]; + + event_file.read(&mut event)?; + assert_eq!(event.data, TOKEN_STREAM); + assert_eq!(event.flags, syscall::EVENT_READ); + println!("-> Readable event"); + + assert_eq!(dup.read(&mut buf)?, 1); + assert_eq!(buf[0], b'a'); + + dup.write(b"b")?; + + event_file.read(&mut event)?; + assert_eq!(event.data, TOKEN_CLIENT); + assert_eq!(event.flags, syscall::EVENT_READ); + println!("-> Readable event"); + + assert_eq!(client.read(&mut buf)?, 1); + assert_eq!(buf[0], b'b'); + + drop(client); + + event_file.read(&mut event)?; + assert_eq!(event.data, TOKEN_STREAM); + println!("-> Readable event (EOF)"); + + assert_eq!(dup.read(&mut buf)?, 0); + + event_file.read(&mut event)?; + assert_eq!(event.data, TOKEN_TIMER); + println!("-> Timed out"); + + println!("Everything tested!"); + Ok(()) +} diff --git a/examples/main.rs b/examples/main.rs index 9b2cddf0c6..af5f58a3a1 100644 --- a/examples/main.rs +++ b/examples/main.rs @@ -85,90 +85,6 @@ fn main() -> io::Result<()> { } println!("-> Accept would block"); - println!("Testing events..."); - - let thread = thread::spawn(move || -> io::Result<()> { - println!("--> Thread: Sleeping for 1 second..."); - thread::sleep(Duration::from_secs(1)); - println!("--> Thread: Writing..."); - client.write(b"hello")?; - client.flush()?; - println!("--> Thread: Sleeping for 1 second..."); - thread::sleep(Duration::from_secs(1)); - println!("--> Thread: Dropping..."); - drop(client); - println!("--> Thread: Sleeping for 3 seconds..."); - thread::sleep(Duration::from_secs(3)); - println!("--> Thread: Opening new..."); - let mut client = File::open("chan:hello_world")?; - let mut buf = [0; 5]; - assert_eq!(client.read(&mut buf)?, 0); - println!("--> Thread: Closing..."); - Ok(()) - }); - - let mut event_file = File::open("event:")?; - let mut time_file = File::open(format!("time:{}", syscall::CLOCK_MONOTONIC))?; - - let mut time = syscall::TimeSpec::default(); - time_file.read(&mut time)?; - time.tv_sec += 3; - time_file.write(&time)?; - - event_file.write(&syscall::Event { - id: dup.as_raw_fd(), - flags: syscall::EVENT_READ | syscall::EVENT_WRITE, - data: 0 - })?; - event_file.write(&syscall::Event { - id: server.as_raw_fd(), - flags: syscall::EVENT_WRITE | syscall::EVENT_READ, - data: 1 - })?; - event_file.write(&syscall::Event { - id: time_file.as_raw_fd(), - flags: syscall::EVENT_READ, - data: 2 - })?; - - let mut event = syscall::Event::default(); - - event_file.read(&mut event)?; - assert_eq!(event.id, dup.as_raw_fd()); - assert_eq!(event.flags, syscall::EVENT_WRITE); - assert_eq!(event.data, 0); - println!("-> Writable event"); - - for _ in 0..2 { - event_file.read(&mut event)?; - assert_eq!(event.id, dup.as_raw_fd()); - assert_eq!(event.flags, syscall::EVENT_READ); - assert_eq!(event.data, 0); - println!("-> Readable event"); - - dup.read(&mut buf)?; - } - - event_file.read(&mut event)?; - assert_eq!(event.id, time_file.as_raw_fd()); - assert_eq!(event.flags, syscall::EVENT_READ); - assert_eq!(event.data, 2); - println!("-> Timed out"); - - event_file.read(&mut event)?; - assert_eq!(event.id, server.as_raw_fd()); - assert_eq!(event.flags, syscall::EVENT_WRITE); - assert_eq!(event.data, 1); - println!("-> Read accept event"); - - let dup = syscall::dup(server.as_raw_fd(), b"listen").map_err(from_syscall_error)?; - let dup = unsafe { File::from_raw_fd(dup) }; - - drop(dup); - - thread.join().unwrap()?; - println!("Everything tested!"); - Ok(()) } diff --git a/src/scheme.rs b/src/scheme.rs index 73ae5a3761..13f721b301 100644 --- a/src/scheme.rs +++ b/src/scheme.rs @@ -67,9 +67,11 @@ impl ChanScheme { handle.notified_write = false; } } else { - if !handle.notified_write { - handle.notified_write = true; - post_fevent(file, *id, EVENT_WRITE)?; + if let Connection::Open(_) = handle.remote { + if !handle.notified_write { + handle.notified_write = true; + post_fevent(file, *id, EVENT_WRITE)?; + } } if !handle.buffer.is_empty() || handle.remote == Connection::Closed { if !handle.notified_read {