maolan_plugin_protocol/
events.rs1use std::io;
2use std::os::unix::io::RawFd;
3use std::time::Duration;
4
5pub struct EventPair {
11 daw_to_host: [RawFd; 2],
12 host_to_daw: [RawFd; 2],
13}
14
15impl EventPair {
16 pub fn new() -> io::Result<Self> {
18 let mut daw_to_host = [0; 2];
19 let mut host_to_daw = [0; 2];
20 if unsafe { libc::pipe(daw_to_host.as_mut_ptr()) } != 0 {
21 return Err(io::Error::last_os_error());
22 }
23 if unsafe { libc::pipe(host_to_daw.as_mut_ptr()) } != 0 {
24 unsafe {
25 libc::close(daw_to_host[0]);
26 libc::close(daw_to_host[1]);
27 }
28 return Err(io::Error::last_os_error());
29 }
30 Ok(Self {
31 daw_to_host,
32 host_to_daw,
33 })
34 }
35
36 pub unsafe fn from_fds(daw_to_host_read: RawFd, host_to_daw_write: RawFd) -> Self {
40 let mut pair = Self {
41 daw_to_host: [daw_to_host_read, -1],
42 host_to_daw: [-1, host_to_daw_write],
43 };
44 pair.close_host_unused();
45 pair
46 }
47
48 pub fn daw_write_fd(&self) -> RawFd {
51 self.daw_to_host[1]
52 }
53
54 pub fn daw_read_fd(&self) -> RawFd {
55 self.host_to_daw[0]
56 }
57
58 pub fn signal_host(&self) -> io::Result<()> {
60 write_byte(self.daw_to_host[1])
61 }
62
63 pub fn wait_host(&self, timeout: Duration) -> io::Result<()> {
65 read_byte(self.host_to_daw[0], timeout)
66 }
67
68 pub fn host_read_fd(&self) -> RawFd {
71 self.daw_to_host[0]
72 }
73
74 pub fn host_write_fd(&self) -> RawFd {
75 self.host_to_daw[1]
76 }
77
78 pub fn wait_daw(&self, timeout: Duration) -> io::Result<()> {
80 read_byte(self.daw_to_host[0], timeout)
81 }
82
83 pub fn signal_daw(&self) -> io::Result<()> {
85 write_byte(self.host_to_daw[1])
86 }
87
88 pub fn close_daw_unused(&mut self) {
91 unsafe {
92 libc::close(self.daw_to_host[0]);
93 libc::close(self.host_to_daw[1]);
94 }
95 self.daw_to_host[0] = -1;
96 self.host_to_daw[1] = -1;
97 }
98
99 pub fn close_host_unused(&mut self) {
102 unsafe {
103 libc::close(self.daw_to_host[1]);
104 libc::close(self.host_to_daw[0]);
105 }
106 self.daw_to_host[1] = -1;
107 self.host_to_daw[0] = -1;
108 }
109}
110
111impl Drop for EventPair {
112 fn drop(&mut self) {
113 unsafe {
114 libc::close(self.daw_to_host[0]);
115 libc::close(self.daw_to_host[1]);
116 libc::close(self.host_to_daw[0]);
117 libc::close(self.host_to_daw[1]);
118 }
119 }
120}
121
122fn write_byte(fd: RawFd) -> io::Result<()> {
123 let buf = [1u8];
124 let n = unsafe { libc::write(fd, buf.as_ptr().cast(), 1) };
125 if n < 0 {
126 Err(io::Error::last_os_error())
127 } else {
128 Ok(())
129 }
130}
131
132fn read_byte(fd: RawFd, timeout: Duration) -> io::Result<()> {
133 let mut pfd = libc::pollfd {
134 fd,
135 events: libc::POLLIN,
136 revents: 0,
137 };
138 let ms = timeout.as_millis().clamp(0, i32::MAX as u128) as i32;
139 let rc = unsafe { libc::poll(&mut pfd, 1, ms) };
140 if rc < 0 {
141 return Err(io::Error::last_os_error());
142 }
143 if rc == 0 {
144 return Err(io::Error::new(io::ErrorKind::TimedOut, "poll timeout"));
145 }
146 let mut buf = [0u8; 1];
147 let n = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), 1) };
148 if n < 0 {
149 Err(io::Error::last_os_error())
150 } else {
151 Ok(())
152 }
153}