Skip to content

Commit

Permalink
add timeout support of poll and select
Browse files Browse the repository at this point in the history
  • Loading branch information
yunwei37 committed Aug 27, 2020
1 parent 8d3f121 commit 8335a7e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 2 deletions.
36 changes: 35 additions & 1 deletion linux-syscall/src/file/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use core::future::Future;
use core::mem::size_of;
use core::pin::Pin;
use core::task::{Context, Poll};
use core::time::Duration;
use kernel_hal::timer_set;
use linux_object::fs::FileDesc;
use linux_object::time::*;

Expand All @@ -30,9 +32,13 @@ impl Syscall<'_> {
#[must_use = "future does nothing unless polled/`await`-ed"]
struct PollFuture<'a> {
polls: &'a mut Vec<PollFd>,
timeout_msecs: usize,
begin_time_ms: usize,
syscall: &'a Syscall<'a>,
}

let begin_time_ms = TimeVal::now().to_msec();

impl<'a> Future for PollFuture<'a> {
type Output = SysResult;

Expand Down Expand Up @@ -72,11 +78,33 @@ impl Syscall<'_> {
if events > 0 {
return Poll::Ready(Ok(events));
}

if self.timeout_msecs == 0 {
// no timeout, return now;
return Poll::Ready(Ok(0));
} else {
let waker = cx.waker().clone();
timer_set(
Duration::from_millis(self.timeout_msecs as u64),
Box::new(move |_| waker.wake()),
);
}

let current_time_ms = TimeVal::now().to_msec();
// infinity check
if self.timeout_msecs < (1 << 31)
&& current_time_ms - self.begin_time_ms >= self.timeout_msecs as usize
{
return Poll::Ready(Ok(0));
}

Poll::Pending
}
}
let future = PollFuture {
polls: &mut polls,
timeout_msecs,
begin_time_ms,
syscall: self,
};
let result = future.await;
Expand Down Expand Up @@ -200,12 +228,18 @@ impl Syscall<'_> {
if self.timeout_msecs == 0 {
// no timeout, return now;
return Poll::Ready(Ok(0));
} else {
let waker = cx.waker().clone();
timer_set(
Duration::from_millis(self.timeout_msecs as u64),
Box::new(move |_| waker.wake()),
);
}

let current_time_ms = TimeVal::now().to_msec();
// infinity check
if self.timeout_msecs < (1 << 31)
&& current_time_ms - self.begin_time_ms > self.timeout_msecs as usize
&& current_time_ms - self.begin_time_ms >= self.timeout_msecs as usize
{
return Poll::Ready(Ok(0));
}
Expand Down
7 changes: 7 additions & 0 deletions linux-syscall/test/testpoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,19 @@ int main(int argc, char **argv)
int pipefd[2];
struct timespec ts;

// test poll using pipe
if (pipe(pipefd) == -1)
{
printf("pipe");
exit(-1);
}

// test time out
fds[0].fd = 0;
fds[0].events = POLLIN;
ret = poll(fds, 1, 1000);
assert(ret == 0);

fds[0].fd = pipefd[0];
fds[0].events = POLLIN;
fds[1].fd = pipefd[1];
Expand Down
3 changes: 2 additions & 1 deletion linux-syscall/test/testselect.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ int main(void)

int pipefd[2];

// test time out 1s
FD_ZERO(&rfds);
FD_SET(0, &rfds);
tv.tv_sec = 0;
tv.tv_sec = 1;
tv.tv_usec = 0;
assert(select(1, &rfds, NULL, NULL, &tv) == 0);
assert(!FD_ISSET(0, &rfds));
Expand Down

0 comments on commit 8335a7e

Please sign in to comment.