smolnetd: Edge-triggered model
Created by: jD91mZM2
Currently smolnetd is level-triggered. This means that when it's writeable, it'll keep announcing itself as writeable over and over. While this is good so you can't miss any events for whatever reason, it means that calling read
on event:
can be more of a busy-loop rather than actually selecting. It also introduces some issues I had to work around with tokio since it relies on a edge-triggered model normally.
Changing to edge-triggered would also mean a blocking read would have to return EWOULDBLOCK instead of just a 0, so there is a way to detect what is a blocking read and what is an EOF. This would once again get rid of some ugly workarounds used in tokio, which is nice.
Minimal example:
extern crate syscall;
use std::{
fs::File,
io::{self, prelude::*},
net::TcpStream,
os::unix::io::AsRawFd
};
use syscall::{Event, EVENT_WRITE};
fn main() -> io::Result<()> {
let mut events = File::open("event:")?;
let stream = TcpStream::connect("google.com:80")?;
events.write(&Event {
id: stream.as_raw_fd(),
flags: EVENT_WRITE,
data: 0
})?;
let mut event = Event::default();
while events.read(&mut event)? > 0 {
println!("{:?}", event);
}
Ok(())
}
You might expect this to print one event when it becomes writeable, but then it continues to send it over and over.