@@ -2,8 +2,7 @@ use crate::errno::Errno;
2
2
use crate :: Result ;
3
3
use libc:: { self , c_int} ;
4
4
use std:: mem;
5
- use std:: os:: unix:: io:: RawFd ;
6
- use std:: ptr;
5
+ use std:: os:: unix:: io:: { FromRawFd , RawFd , OwnedFd , AsFd , AsRawFd } ;
7
6
8
7
libc_bitflags ! (
9
8
pub struct EpollFlags : c_int {
@@ -70,20 +69,126 @@ impl EpollEvent {
70
69
}
71
70
}
72
71
72
+ /// A safe wrapper around [`epoll`](https://man7.org/linux/man-pages/man7/epoll.7.html).
73
+ /// ```
74
+ /// # use nix::sys::{epoll::{Epoll, EpollEvent, EpollFlags, EpollCreateFlags}, eventfd::{eventfd, EfdFlags}};
75
+ /// # use nix::unistd::write;
76
+ /// # use std::os::unix::io::{OwnedFd, FromRawFd, AsRawFd, AsFd};
77
+ /// # use std::time::{Instant, Duration};
78
+ /// # fn main() -> nix::Result<()> {
79
+ /// const DATA: u64 = 17;
80
+ /// const MILLIS: u64 = 100;
81
+ ///
82
+ /// // Create epoll
83
+ /// let epoll = Epoll::new(EpollCreateFlags::empty())?;
84
+ ///
85
+ /// // Create eventfd & Add event
86
+ /// let eventfd = unsafe { OwnedFd::from_raw_fd(eventfd(0, EfdFlags::empty())?) };
87
+ /// epoll.add(&eventfd, EpollEvent::new(EpollFlags::EPOLLIN,DATA))?;
88
+ ///
89
+ /// // Arm eventfd & Time wait
90
+ /// write(eventfd.as_raw_fd(), &1u64.to_ne_bytes())?;
91
+ /// let now = Instant::now();
92
+ ///
93
+ /// // Wait on event
94
+ /// let mut events = [EpollEvent::empty()];
95
+ /// epoll.wait(&mut events, MILLIS as isize)?;
96
+ ///
97
+ /// // Assert data correct & timeout didn't occur
98
+ /// assert_eq!(events[0].data(), DATA);
99
+ /// assert!(now.elapsed() < Duration::from_millis(MILLIS));
100
+ /// # Ok(())
101
+ /// # }
102
+ /// ```
103
+ #[ derive( Debug ) ]
104
+ pub struct Epoll ( pub OwnedFd ) ;
105
+ impl Epoll {
106
+ /// Creates a new epoll instance and returns a file descriptor referring to that instance.
107
+ ///
108
+ /// [`epoll_create1`](https://man7.org/linux/man-pages/man2/epoll_create1.2.html).
109
+ pub fn new ( flags : EpollCreateFlags ) -> Result < Self > {
110
+ let res = unsafe { libc:: epoll_create1 ( flags. bits ( ) ) } ;
111
+ let fd = Errno :: result ( res) ?;
112
+ let owned_fd = unsafe { OwnedFd :: from_raw_fd ( fd) } ;
113
+ Ok ( Self ( owned_fd) )
114
+ }
115
+ /// Add an entry to the interest list of the epoll file descriptor for
116
+ /// specified in events.
117
+ ///
118
+ /// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html) with `EPOLL_CTL_ADD`.
119
+ pub fn add < Fd : AsFd > ( & self , fd : Fd , mut event : EpollEvent ) -> Result < ( ) > {
120
+ self . epoll_ctl ( EpollOp :: EpollCtlAdd , fd, & mut event)
121
+ }
122
+ /// Remove (deregister) the target file descriptor `fd` from the interest list.
123
+ ///
124
+ /// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html) with `EPOLL_CTL_DEL` .
125
+ pub fn delete < Fd : AsFd > ( & self , fd : Fd ) -> Result < ( ) > {
126
+ self . epoll_ctl ( EpollOp :: EpollCtlDel , fd, None )
127
+ }
128
+ /// Change the settings associated with `fd` in the interest list to the new settings specified
129
+ /// in `event`.
130
+ ///
131
+ /// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html) with `EPOLL_CTL_MOD`.
132
+ pub fn modify < Fd : AsFd > ( & self , fd : Fd , event : & mut EpollEvent ) -> Result < ( ) > {
133
+ self . epoll_ctl ( EpollOp :: EpollCtlMod , fd, event)
134
+ }
135
+ /// Waits for I/O events, blocking the calling thread if no events are currently available.
136
+ /// (This can be thought of as fetching items from the ready list of the epoll instance.)
137
+ ///
138
+ /// [`epoll_wait`](https://man7.org/linux/man-pages/man2/epoll_wait.2.html)
139
+ pub fn wait ( & self , events : & mut [ EpollEvent ] , timeout : isize ) -> Result < usize > {
140
+ let res = unsafe {
141
+ libc:: epoll_wait (
142
+ self . 0 . as_raw_fd ( ) ,
143
+ events. as_mut_ptr ( ) as * mut libc:: epoll_event ,
144
+ events. len ( ) as c_int ,
145
+ timeout as c_int ,
146
+ )
147
+ } ;
148
+
149
+ Errno :: result ( res) . map ( |r| r as usize )
150
+ }
151
+ /// This system call is used to add, modify, or remove entries in the interest list of the epoll
152
+ /// instance referred to by `self`. It requests that the operation `op` be performed for the
153
+ /// target file descriptor, `fd`.
154
+ ///
155
+ /// When possible prefer [`Epoll::add`], [`Epoll::delete`] and [`Epoll::modify`].
156
+ ///
157
+ /// [`epoll_ctl`](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html)
158
+ fn epoll_ctl < ' a , Fd : AsFd , T > (
159
+ & self ,
160
+ op : EpollOp ,
161
+ fd : Fd ,
162
+ event : T ,
163
+ ) -> Result < ( ) >
164
+ where
165
+ T : Into < Option < & ' a mut EpollEvent > > ,
166
+ {
167
+ let event: Option < & mut EpollEvent > = event. into ( ) ;
168
+ let ptr = event. map ( |x|& mut x. event as * mut libc:: epoll_event ) . unwrap_or ( std:: ptr:: null_mut ( ) ) ;
169
+ unsafe {
170
+ Errno :: result ( libc:: epoll_ctl ( self . 0 . as_raw_fd ( ) , op as c_int , fd. as_fd ( ) . as_raw_fd ( ) , ptr) ) . map ( drop)
171
+ }
172
+ }
173
+ }
174
+
175
+ #[ deprecated( since = "0.27.0" , note = "Use Epoll::new() instead" ) ]
73
176
#[ inline]
74
177
pub fn epoll_create ( ) -> Result < RawFd > {
75
178
let res = unsafe { libc:: epoll_create ( 1024 ) } ;
76
179
77
180
Errno :: result ( res)
78
181
}
79
182
183
+ #[ deprecated( since = "0.27.0" , note = "Use Epoll::new() instead" ) ]
80
184
#[ inline]
81
185
pub fn epoll_create1 ( flags : EpollCreateFlags ) -> Result < RawFd > {
82
186
let res = unsafe { libc:: epoll_create1 ( flags. bits ( ) ) } ;
83
187
84
188
Errno :: result ( res)
85
189
}
86
190
191
+ #[ deprecated( since = "0.27.0" , note = "Use Epoll::epoll_ctl() instead" ) ]
87
192
#[ inline]
88
193
pub fn epoll_ctl < ' a , T > (
89
194
epfd : RawFd ,
@@ -102,13 +207,14 @@ where
102
207
if let Some ( ref mut event) = event {
103
208
libc:: epoll_ctl ( epfd, op as c_int , fd, & mut event. event )
104
209
} else {
105
- libc:: epoll_ctl ( epfd, op as c_int , fd, ptr:: null_mut ( ) )
210
+ libc:: epoll_ctl ( epfd, op as c_int , fd, std :: ptr:: null_mut ( ) )
106
211
}
107
212
} ;
108
213
Errno :: result ( res) . map ( drop)
109
214
}
110
215
}
111
216
217
+ #[ deprecated( since = "0.27.0" , note = "Use Epoll::wait() instead" ) ]
112
218
#[ inline]
113
219
pub fn epoll_wait (
114
220
epfd : RawFd ,
@@ -125,4 +231,4 @@ pub fn epoll_wait(
125
231
} ;
126
232
127
233
Errno :: result ( res) . map ( |r| r as usize )
128
- }
234
+ }
0 commit comments