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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
use std::os::unix::io::AsRawFd; use std::io::Result; use std::fmt::Debug; use event::Event; use channel::{channel, sync_channel, Sender, SyncSender, Receiver}; #[cfg(any(target_os = "linux", target_os = "android"))] use epoll::KernelRegistrar; #[cfg(any(target_os = "bitrig", target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd"))] pub use kqueue::KernelRegistrar; /// An abstraction for registering file descriptors with a kernel poller /// /// A Registrar is tied to a Poller of the same type, and registers sockets and unique IDs for those /// sockets as userdata that can be waited on by the poller. A Registar should only be retrieved via /// a call to Poller::get_registrar(&self), and not created on it's own. #[derive(Debug, Clone)] pub struct Registrar { inner: KernelRegistrar } impl Registrar { /// This method is public only so it can be used directly by the Poller. Do not Use it. #[doc(hidden)] pub fn new(inner: KernelRegistrar) -> Registrar { Registrar { inner: inner } } /// Register a socket for a given event type, with a Poller and return it's unique ID /// /// Note that if the sock type is not pollable, then an error will be returned. pub fn register<T: AsRawFd>(&self, sock: &T, event: Event) -> Result<usize> { self.inner.register(sock, event) } /// Reregister a socket with a Poller pub fn reregister<T: AsRawFd>(&self, id: usize, sock: &T, event: Event) -> Result<()> { self.inner.reregister(id, sock, event) } /// Remove a socket from a Poller /// /// Will return an error if the socket is not present in the poller when using epoll. Returns no /// error with kqueue. pub fn deregister<T: AsRawFd>(&self, sock: &T) -> Result<()> { self.inner.deregister(sock) } /// Set a timeout in ms that fires once /// /// Note that this timeout may be delivered late due to the time taken between the calls to /// `Poller::wait()` exceeding the timeout, but it will never be delivered early. /// /// Note that an error will be returned if the maximum number of file descriptors is already /// registered with the kernel poller. pub fn set_timeout(&self, timeout: usize) -> Result<usize> { self.inner.set_timeout(timeout) } /// Set a recurring timeout in ms /// /// A notification with the returned id will be sent at the given interval. The timeout can be /// cancelled with a call to `cancel_timeout()` /// /// Note that if `Poller::wait()` is not called in a loop, these timeouts as well as other /// notifications, will not be delivered. Timeouts may be delivered late, due to the time taken /// between calls to `Poller::wait()` exceeding the timeout, but will never be delivered early. /// /// Note that an error will be returned if the maximum number of file descriptors is already /// registered with the kernel poller. pub fn set_interval(&self, interval: usize) -> Result<usize> { self.inner.set_interval(interval) } /// Cancel a recurring timeout. /// /// Note that there may be timeouts in flight already that were not yet cancelled, so it is /// possible that you may receive notifications after the timeout was cancelled. This can be /// mitigated by keeping track of live timers and only processing timeout events for known live /// timers. /// /// An error will be returned if the timer is not registered with the kernel poller. pub fn cancel_timeout(&self, timer_id: usize) -> Result<()> { self.inner.cancel_timeout(timer_id) } /// Create an asynchronous mpsc channel where the Receiver is registered with the kernel poller. /// /// Each new Receiver gets registered using a user space event mechanism (either eventfd or /// kevent depending upon OS). When a send occurs the kernel notification mechanism (a syscall on /// a file descriptor) will be issued to alert the kernel poller to wakeup and issue a /// notification for the Receiver. However, since syscalls are expensive, an optimization is /// made where if the kernel poller is already set to awaken, or currently processing events, a /// new syscall will not be made. /// /// Standard rust mpsc channels are used internally and have non-blocking semantics. Note that /// the return type is different since the Receiver is being registered with the kernel poller /// and this can fail. /// /// When a Receiver is dropped it will become unregistered. pub fn channel<T: Debug>(&mut self) -> Result<(Sender<T>, Receiver<T>)> { channel(&mut self.inner) } /// Create a synchronous mpsc channel where the Receiver is registered with the kernel poller. /// /// Each new Receiver gets registered using a user space event mechanism (either eventfd or /// kevent depending upon OS). When a send occurs the kernel notification mechanism (a syscall on /// a file descriptor) will be issued to alert the kernel poller to wakeup and issue a /// notification for the Receiver. However, since syscalls are expensive, an optimization is /// made where if the kernel poller is already set to awaken, or currently processing events, a /// new syscall will not be made. /// /// Standard rust synchronous mpsc channels are used internally and block when the queue is /// full, as given by the bound in the construcotr. Note that the return type is different /// since the Receiver is being registered with the kernel poller and this can fail. /// /// When a Receiver is dropped it will become unregistered. pub fn sync_channel<T: Debug>(&mut self, bound: usize) -> Result<(SyncSender<T>, Receiver<T>)> { sync_channel(&mut self.inner, bound) } }