Skip to content

Commit 1b3725d

Browse files
committed
document poll module
1 parent 7c69781 commit 1b3725d

File tree

1 file changed

+92
-1
lines changed

1 file changed

+92
-1
lines changed

src/poll.rs

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,29 @@
22
use sys::time::TimeSpec;
33
#[cfg(any(target_os = "linux", target_os = "android", target_os = "freebsd", target_os = "dragonfly"))]
44
use sys::signal::SigSet;
5+
use std::os::unix::io::RawFd;
56

67
use libc;
78
use {Errno, Result};
89

10+
/// This is a wrapper around `libc::pollfd`.
11+
///
12+
/// It's meant to be used as an argument to the [`poll`](fn.poll.html) and
13+
/// [`ppoll`](fn.ppoll.html) functions to specify the events of interested
14+
/// for a specific file descriptor.
15+
///
16+
/// After a call to `poll` or `ppoll`, the events that occured can be
17+
/// retrieved by calling [`revents()`](#method.revents) on the `PollFd`.
918
#[repr(C)]
1019
#[derive(Clone, Copy)]
1120
pub struct PollFd {
1221
pollfd: libc::pollfd,
1322
}
1423

1524
impl PollFd {
16-
pub fn new(fd: libc::c_int, events: EventFlags) -> PollFd {
25+
/// Creates a new `PollFd` specifying the events of interested
26+
/// for a given file descriptor.
27+
pub fn new(fd: RawFd, events: EventFlags) -> PollFd {
1728
PollFd {
1829
pollfd: libc::pollfd {
1930
fd: fd,
@@ -23,26 +34,81 @@ impl PollFd {
2334
}
2435
}
2536

37+
/// Returns the events that occured in the last call to `poll` or `ppoll`.
2638
pub fn revents(&self) -> Option<EventFlags> {
2739
EventFlags::from_bits(self.pollfd.revents)
2840
}
2941
}
3042

3143
libc_bitflags! {
3244
pub flags EventFlags: libc::c_short {
45+
/// There is data to read.
3346
POLLIN,
47+
/// There is some exceptional condition on the file descriptor.
48+
///
49+
/// Possibilities include:
50+
///
51+
/// * There is out-of-band data on a TCP socket (see
52+
/// [tcp(7)](http://man7.org/linux/man-pages/man7/tcp.7.html)).
53+
/// * A pseudoterminal master in packet mode has seen a state
54+
/// change on the slave (see
55+
/// [ioctl_tty(2)](http://man7.org/linux/man-pages/man2/ioctl_tty.2.html)).
56+
/// * A cgroup.events file has been modified (see
57+
/// [cgroups(7)](http://man7.org/linux/man-pages/man7/cgroups.7.html)).
3458
POLLPRI,
59+
/// Writing is now possible, though a write larger that the
60+
/// available space in a socket or pipe will still block (unless
61+
/// `O_NONBLOCK` is set).
3562
POLLOUT,
63+
/// Equivalent to [`POLLIN`](constant.POLLIN.html)
3664
POLLRDNORM,
65+
/// Equivalent to [`POLLOUT`](constant.POLLOUT.html)
3766
POLLWRNORM,
67+
/// Priority band data can be read (generally unused on Linux).
3868
POLLRDBAND,
69+
/// Priority data may be written.
3970
POLLWRBAND,
71+
/// Error condition (only returned in
72+
/// [`PollFd::revents`](struct.PollFd.html#method.revents);
73+
/// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
74+
/// This bit is also set for a file descriptor referring to the
75+
/// write end of a pipe when the read end has been closed.
4076
POLLERR,
77+
/// Hang up (only returned in [`PollFd::revents`](struct.PollFd.html#method.revents);
78+
/// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
79+
/// Note that when reading from a channel such as a pipe or a stream
80+
/// socket, this event merely indicates that the peer closed its
81+
/// end of the channel. Subsequent reads from the channel will
82+
/// return 0 (end of file) only after all outstanding data in the
83+
/// channel has been consumed.
4184
POLLHUP,
85+
/// Invalid request: `fd` not open (only returned in
86+
/// [`PollFd::revents`](struct.PollFd.html#method.revents);
87+
/// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
4288
POLLNVAL,
4389
}
4490
}
4591

92+
/// `poll` waits for one of a set of file descriptors to become ready to perform I/O.
93+
/// ([`poll(2)`](http://man7.org/linux/man-pages/man2/poll.2.html))
94+
///
95+
/// `fds` is a slice containing all [`PollFd`](struct.PollFd.html) to poll.
96+
/// The function will return as soon as one event registered in one of the `PollFd` occurs.
97+
///
98+
/// The `timeout` argument specifies the number of milliseconds that `poll()`
99+
/// should block waiting for a file descriptor to become ready. The call
100+
/// will block until either:
101+
///
102+
/// * a file descriptor becomes ready;
103+
/// * the call is interrupted by a signal handler; or
104+
/// * the timeout expires.
105+
///
106+
/// Note that the timeout interval will be rounded up to the system clock
107+
/// granularity, and kernel scheduling delays mean that the blocking
108+
/// interval may overrun by a small amount. Specifying a negative value
109+
/// in timeout means an infinite timeout. Specifying a timeout of zero
110+
/// causes `poll()` to return immediately, even if no file descriptors are
111+
/// ready.
46112
pub fn poll(fds: &mut [PollFd], timeout: libc::c_int) -> Result<libc::c_int> {
47113
let res = unsafe {
48114
libc::poll(fds.as_mut_ptr() as *mut libc::pollfd,
@@ -53,6 +119,31 @@ pub fn poll(fds: &mut [PollFd], timeout: libc::c_int) -> Result<libc::c_int> {
53119
Errno::result(res)
54120
}
55121

122+
/// `ppoll()` allows an application to safely wait until either a file
123+
/// descriptor becomes ready or until a signal is caught.
124+
/// ([`poll(2)`](http://man7.org/linux/man-pages/man2/poll.2.html))
125+
///
126+
/// The operation of `ppoll` is identical to `poll`, other than these two differences:
127+
///
128+
/// * `timeout` is a `TimeSpec` which can specify time with nanosecond precision.
129+
/// * `ppoll` changes the signal set whose delivery are blocked for the caller before polling
130+
/// the file descriptors. This set is reverted after the polling.
131+
/// Note that this is done **atomically**.
132+
///
133+
/// It is equivalent to *atomically* executing the following calls
134+
/// (expressed here in C):
135+
///
136+
/// ```c
137+
/// sigset_t origmask;
138+
/// int timeout;
139+
///
140+
/// timeout = (tmo_p == NULL) ? -1 :
141+
/// (tmo_p->tv_sec * 1000 + tmo_p->tv_nsec / 1000000);
142+
/// pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
143+
/// ready = poll(&fds, nfds, timeout);
144+
/// pthread_sigmask(SIG_SETMASK, &origmask, NULL);
145+
/// ```
146+
///
56147
#[cfg(any(target_os = "linux", target_os = "android", target_os = "freebsd", target_os = "dragonfly"))]
57148
pub fn ppoll(fds: &mut [PollFd], timeout: TimeSpec, sigmask: SigSet) -> Result<libc::c_int> {
58149

0 commit comments

Comments
 (0)