]>
Commit | Line | Data |
---|---|---|
5bd0c562 WB |
1 | use std::io; |
2 | use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; | |
3 | use std::task::{Context, Poll}; | |
4 | ||
7a1ab2b2 | 5 | use tokio::io::unix::AsyncFd; |
5bd0c562 WB |
6 | |
7 | use crate::tools::Fd; | |
8 | ||
9 | #[repr(transparent)] | |
10 | pub struct EventedFd { | |
11 | fd: Fd, | |
12 | } | |
13 | ||
14 | impl EventedFd { | |
15 | #[inline] | |
16 | pub fn new(fd: Fd) -> Self { | |
17 | Self { fd } | |
18 | } | |
19 | } | |
20 | ||
21 | impl AsRawFd for EventedFd { | |
22 | #[inline] | |
23 | fn as_raw_fd(&self) -> RawFd { | |
24 | self.fd.as_raw_fd() | |
25 | } | |
26 | } | |
27 | ||
28 | impl FromRawFd for EventedFd { | |
29 | #[inline] | |
30 | unsafe fn from_raw_fd(fd: RawFd) -> Self { | |
4032c669 | 31 | Self::new(unsafe { Fd::from_raw_fd(fd) }) |
5bd0c562 WB |
32 | } |
33 | } | |
34 | ||
35 | impl IntoRawFd for EventedFd { | |
36 | #[inline] | |
37 | fn into_raw_fd(self) -> RawFd { | |
38 | self.fd.into_raw_fd() | |
39 | } | |
40 | } | |
41 | ||
5bd0c562 WB |
42 | #[repr(transparent)] |
43 | pub struct PolledFd { | |
7a1ab2b2 | 44 | fd: AsyncFd<EventedFd>, |
5bd0c562 WB |
45 | } |
46 | ||
47 | impl PolledFd { | |
48 | pub fn new(fd: Fd) -> tokio::io::Result<Self> { | |
49 | Ok(Self { | |
7a1ab2b2 | 50 | fd: AsyncFd::new(EventedFd::new(fd))?, |
5bd0c562 WB |
51 | }) |
52 | } | |
53 | ||
54 | pub fn wrap_read<T>( | |
55 | &self, | |
56 | cx: &mut Context, | |
57 | func: impl FnOnce() -> io::Result<T>, | |
58 | ) -> Poll<io::Result<T>> { | |
7a1ab2b2 | 59 | let mut ready_guard = ready!(self.fd.poll_read_ready(cx))?; |
5bd0c562 WB |
60 | match func() { |
61 | Ok(out) => Poll::Ready(Ok(out)), | |
62 | Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => { | |
7a1ab2b2 | 63 | ready_guard.clear_ready(); |
5bd0c562 WB |
64 | Poll::Pending |
65 | } | |
66 | Err(err) => Poll::Ready(Err(err)), | |
67 | } | |
68 | } | |
69 | ||
70 | pub fn wrap_write<T>( | |
71 | &self, | |
72 | cx: &mut Context, | |
73 | func: impl FnOnce() -> io::Result<T>, | |
74 | ) -> Poll<io::Result<T>> { | |
7a1ab2b2 | 75 | let mut ready_guard = ready!(self.fd.poll_write_ready(cx))?; |
5bd0c562 WB |
76 | match func() { |
77 | Ok(out) => Poll::Ready(Ok(out)), | |
78 | Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => { | |
7a1ab2b2 | 79 | ready_guard.clear_ready(); |
5bd0c562 WB |
80 | Poll::Pending |
81 | } | |
82 | Err(err) => Poll::Ready(Err(err)), | |
83 | } | |
84 | } | |
85 | } | |
86 | ||
87 | impl AsRawFd for PolledFd { | |
88 | #[inline] | |
89 | fn as_raw_fd(&self) -> RawFd { | |
90 | self.fd.get_ref().as_raw_fd() | |
91 | } | |
92 | } | |
93 | ||
94 | impl IntoRawFd for PolledFd { | |
95 | #[inline] | |
96 | fn into_raw_fd(self) -> RawFd { | |
97 | // for the kind of resource we're managing it should always be possible to extract it from | |
98 | // its driver | |
82613319 | 99 | self.fd.into_inner().into_raw_fd() |
5bd0c562 WB |
100 | } |
101 | } |