Fix events & more event tests
This commit is contained in:
@@ -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(())
|
||||
}
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
+5
-3
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user