Switch to an edge-triggered event system (#28)

This commit is contained in:
jD91mZM2
2018-05-30 17:25:57 +02:00
committed by Jeremy Soller
parent 3a92b2c466
commit 6ffe327989
3 changed files with 35 additions and 9 deletions
+26 -4
View File
@@ -28,6 +28,8 @@ pub struct SocketFile<DataT> {
events: usize,
socket_handle: SocketHandle,
read_notified: bool,
write_notified: bool,
read_timeout: Option<TimeSpec>,
write_timeout: Option<TimeSpec>,
}
@@ -37,6 +39,8 @@ impl<DataT> SocketFile<DataT> {
SocketFile {
flags: self.flags,
events: self.events,
read_notified: false, // we still want to notify about this new socket
write_notified: false,
read_timeout: self.read_timeout,
write_timeout: self.write_timeout,
socket_handle: self.socket_handle,
@@ -48,6 +52,8 @@ impl<DataT> SocketFile<DataT> {
SocketFile {
flags: 0,
events: 0,
read_notified: false,
write_notified: false,
read_timeout: None,
write_timeout: None,
socket_handle,
@@ -198,10 +204,12 @@ where
pub fn notify_sockets(&mut self) -> Result<()> {
// Notify non-blocking sockets
for (&fd, file) in &self.files {
if let SchemeFile::Socket(SocketFile {
for (&fd, ref mut file) in &mut self.files {
if let &mut SchemeFile::Socket(SocketFile {
socket_handle,
events,
ref mut read_notified,
ref mut write_notified,
..
}) = *file
{
@@ -209,11 +217,21 @@ where
let socket = socket_set.get::<SocketT>(socket_handle);
if events & syscall::EVENT_READ == syscall::EVENT_READ && socket.can_recv() {
post_fevent(&mut self.scheme_file, fd, syscall::EVENT_READ, 1)?;
if !*read_notified {
post_fevent(&mut self.scheme_file, fd, syscall::EVENT_READ, 1)?;
*read_notified = true;
}
} else {
*read_notified = false;
}
if events & syscall::EVENT_WRITE == syscall::EVENT_WRITE && socket.can_send() {
post_fevent(&mut self.scheme_file, fd, syscall::EVENT_WRITE, 1)?;
if !*write_notified {
post_fevent(&mut self.scheme_file, fd, syscall::EVENT_WRITE, 1)?;
*write_notified = true;
}
} else {
*write_notified = false;
}
}
}
@@ -488,6 +506,8 @@ where
flags,
events: 0,
socket_handle,
read_notified: false,
write_notified: false,
write_timeout: None,
read_timeout: None,
data,
@@ -663,6 +683,8 @@ where
SchemeFile::Setting(_) => Err(SyscallError::new(syscall::EBADF)),
SchemeFile::Socket(ref mut file) => {
file.events = events;
file.read_notified = false; // resend missed events
file.write_notified = false;
Ok(fd)
}
}
+7 -3
View File
@@ -120,7 +120,7 @@ impl<'a> SchemeSocket for TcpSocket<'a> {
self.send_slice(buf).expect("Can't send slice");
Ok(buf.len())
} else if file.flags & syscall::O_NONBLOCK == syscall::O_NONBLOCK {
Ok(0)
Err(SyscallError::new(syscall::EAGAIN))
} else {
Err(SyscallError::new(syscall::EWOULDBLOCK))
}
@@ -137,7 +137,7 @@ impl<'a> SchemeSocket for TcpSocket<'a> {
let length = self.recv_slice(buf).expect("Can't receive slice");
Ok(length)
} else if file.flags & syscall::O_NONBLOCK == syscall::O_NONBLOCK {
Ok(0)
Err(SyscallError::new(syscall::EAGAIN))
} else {
Err(SyscallError::new(syscall::EWOULDBLOCK))
}
@@ -159,7 +159,11 @@ impl<'a> SchemeSocket for TcpSocket<'a> {
let file = match path {
"listen" => if let SchemeFile::Socket(ref tcp_handle) = *file {
if !is_active {
return Err(SyscallError::new(syscall::EWOULDBLOCK));
if tcp_handle.flags & syscall::O_NONBLOCK == syscall::O_NONBLOCK {
return Err(SyscallError::new(syscall::EAGAIN));
} else {
return Err(SyscallError::new(syscall::EWOULDBLOCK));
}
}
trace!("TCP creating new listening socket");
let new_handle = SchemeFile::Socket(tcp_handle.clone_with_data(()));
+2 -2
View File
@@ -117,7 +117,7 @@ impl<'a, 'b> SchemeSocket for UdpSocket<'a, 'b> {
self.send_slice(buf, file.data).expect("Can't send slice");
Ok(buf.len())
} else if file.flags & syscall::O_NONBLOCK == syscall::O_NONBLOCK {
Ok(0)
Err(SyscallError::new(syscall::EAGAIN))
} else {
Err(SyscallError::new(syscall::EWOULDBLOCK))
}
@@ -132,7 +132,7 @@ impl<'a, 'b> SchemeSocket for UdpSocket<'a, 'b> {
let (length, _) = self.recv_slice(buf).expect("Can't receive slice");
Ok(length)
} else if file.flags & syscall::O_NONBLOCK == syscall::O_NONBLOCK {
Ok(0)
Err(SyscallError::new(syscall::EAGAIN))
} else {
Err(SyscallError::new(syscall::EWOULDBLOCK))
}