Create Your Own Event Queue 84 The operation we want to perform on the epoll queue is adding interest in events on a new file descriptor. Therefore, we set the op argument to the ffi::EPOLL_CTL_ADD constant value. Next up is the call to ffi::epoll_ctl. We pass in the file descriptor to the epoll instance first, then we pass in the op argument to indicate what kind of operation we want to perform. The last two arguments are the file descriptor we want the queue to track and the Event object we created to indicate what kind of events we're interested in getting notifications for. The last part of the function body is simply the error handling, which should be familiar by now. The last part of poll. rs is the Drop implementation for Registry : ch04/a-epoll/src/poll. rs impl Drop for Registry { fn drop(&mut self) { let res = unsafe { ffi::close(self. raw_fd) }; if res < 0 { let err = io::Error::last_os_error(); eprintln!("ERROR: {err:?}"); } } } The Drop implementation simply calls ffi::close on the epoll file descriptor. Adding a panic to drop is rarely a good idea since drop can be called within a panic already, which will cause the process to simply abort. mio logs errors if they occur in its Drop implementation but doesn't handle them in any other way. For our simple example, we'll just print the error so we can see if anything goes wrong since we don't implement any kind of logging here. The last part is the code for running our example, and that leads us to main. rs. The main program Let's see how it all works in practice. Make sure that delayserver is up and running, because we'll need it for these examples to work. The goal is to send a set of requests to delayserver with varying delays and then use epoll to wait for the responses. Therefore, we'll only use epoll to track read events in this example. The program doesn't do much more than that for now. 