mio_st/poll/option.rs
1/// Option supplied when [registering] an `Evented` handle with `Poller`.
2///
3/// `PollOption` values can be combined together using the various bitwise
4/// operators.
5///
6/// For high level documentation on polling see [`Poller`].
7///
8/// [registering]: struct.Poller.html#method.register
9/// [`Poller`]: struct.Poller.html
10///
11/// # Difference
12///
13/// An [`Evented`] registration may request [edge-triggered] or
14/// [level-triggered] or [oneshot] events. `Evented` handle registered with
15/// oneshot polling option will only receive a single event and then have to
16/// [reregister] too receive more events.
17///
18/// The difference between the edge-triggered and level-trigger can be described
19/// as follows. Supposed that this scenario happens:
20///
21/// 1. A [`TcpStream`] is registered with `Poller`.
22/// 2. The socket receives 2kb of data.
23/// 3. A call to [`Poller.poll`] returns the id associated with the socket
24///    indicating readable readiness.
25/// 4. 1kb is read from the socket.
26/// 5. Another call to [`Poller.poll`] is made.
27///
28/// If when the socket was registered with `Poller`, and *edge*-triggered events
29/// were requested, then the call to [`Poller.poll`] done in step **5** will
30/// (probably) block despite there being another 1kb still present in the socket
31/// read buffer. The reason for this is that edge-triggered mode delivers events
32/// only when changes occur on the monitored [`Evented`]. So, in step *5* the
33/// caller might end up waiting for some data that is already present inside the
34/// socket buffer.
35///
36/// With edge-triggered events, operations **must** be performed on the
37/// `Evented` type until [`WouldBlock`] is returned. In other words, after
38/// receiving an event indicating readiness for a certain operation, one should
39/// assume that [`Poller.poll`] may never return another event for the same id
40/// and readiness until the operation returns [`WouldBlock`].
41///
42/// By contrast, when *level*-triggered notifications was requested, each call
43/// to [`Poller.poll`] will return an event for the socket as long as data
44/// remains in the socket buffer. Though generally, level-triggered events
45/// should be avoided if high performance is a concern.
46///
47/// Since even with edge-triggered events, multiple events can be generated upon
48/// receipt of multiple chunks of data, the caller has the option to set the
49/// oneshot flag. This tells `Poller` to disable the associated [`Evented`]
50/// after the event is returned from [`Poller.poll`], note that *disabled* and
51/// *deregistered* are not the same thing. Subsequent calls to [`Poller.poll`]
52/// will no longer include events for [`Evented`] handles that are disabled even
53/// if the readiness state changes. The handle can be re-enabled by calling
54/// [`reregister`]. When handles are disabled, internal resources used to
55/// monitor the handle are maintained until the handle is deregistered. This
56/// makes re-registering the handle a fast operation.
57///
58/// For example, in the following scenario:
59///
60/// 1. A [`TcpStream`] is registered with `Poller`.
61/// 2. The socket receives 2kb of data.
62/// 3. A call to [`Poller.poll`] returns the id associated with the socket
63///    indicating readable readiness.
64/// 4. 2kb is read from the socket.
65/// 5. Another call to read is issued and [`WouldBlock`] is returned
66/// 6. The socket receives another 2kb of data.
67/// 7. Another call to [`Poller.poll`] is made.
68///
69/// Assuming the socket was registered with `Poller` with the *oneshot* option,
70/// then the call to [`Poller.poll`] in step 7 would block. This is because,
71/// oneshot tells `Poller` to disable events for the socket after returning an
72/// event.
73///
74/// In order to receive the event for the data received in step 6, the socket
75/// would need to be reregistered using [`reregister`].
76///
77/// [`Evented`]: ../event/trait.Evented.html
78/// [edge-triggered]: #variant.Edge
79/// [level-triggered]: #variant.Level
80/// [oneshot]: #variant.Oneshot
81/// [reregister]: struct.Poller.html#method.reregister
82/// [`TcpStream`]: ../net/struct.TcpStream.html
83/// [`Poller.poll`]: struct.Poller.html#method.poll
84/// [`WouldBlock`]: https://doc.rust-lang.org/nightly/std/io/enum.ErrorKind.html#variant.WouldBlock
85/// [`reregister`]: struct.Poller.html#method.reregister
86#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
87pub enum PollOption {
88    /// Edge-triggered notifications.
89    Edge,
90    /// Level-triggered notifications.
91    Level,
92    /// Oneshot notifications.
93    Oneshot,
94}