1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
use super::super::types::Argv;
use super::Alloc;
use crate::guest::alloc::{Allocator, Collector, Output};
use crate::libc::{epoll_event, SYS_epoll_wait};
use crate::Result;
use core::ffi::{c_int, c_long};
pub struct EpollWait<'a> {
pub epfd: c_int,
pub events: &'a mut [epoll_event],
pub timeout: c_int,
}
unsafe impl<'a> Alloc<'a> for EpollWait<'a> {
const NUM: c_long = SYS_epoll_wait;
type Argv = Argv<4>;
type Ret = c_int;
type Staged = Output<'a, [epoll_event], &'a mut [epoll_event]>;
type Committed = Self::Staged;
type Collected = Option<Result<c_int>>;
fn stage(self, alloc: &mut impl Allocator) -> Result<(Self::Argv, Self::Staged)> {
let events = Output::stage_slice(alloc, self.events)?;
Ok((
Argv([
self.epfd as _,
events.offset(),
events.len(),
self.timeout as _,
]),
events,
))
}
fn collect(
events: Self::Committed,
ret: Result<Self::Ret>,
col: &impl Collector,
) -> Self::Collected {
match ret {
Ok(ret) if ret as usize > events.len() => None,
res @ Ok(ret) => {
unsafe { events.collect_range(col, 0..ret as _) };
Some(res)
}
err => Some(err),
}
}
}