|
| 1 | +## Poll |
| 2 | + |
| 3 | +The `poll` functions perform timed waits on one or more [file handles](filehandle.html). |
| 4 | + |
| 5 | +Mbed OS provides `poll()` in two forms: |
| 6 | + |
| 7 | +- `int poll(struct pollfd fds[], nfds_t nfds, int timeout)` the standard POSIX form taking an array of integer file descriptors. |
| 8 | +- `int mbed::poll(pollfh fhs[], unsigned nfhs, int timeout)`, the variant taking an array of `FileHandle *`. |
| 9 | + |
| 10 | +See the POSIX specification of `poll` for full details of the API. Mbed OS provides the `POLLIN`, `POLLOUT`, `POLLERR` and `POLLHUP` event flags, but implementation depends on the device. |
| 11 | + |
| 12 | +Note that the `poll` is not affected by the blocking or nonblocking setting of the individual file handles. The `timeout` argument always determines the wait behavior: 0 for immediate (nonblocking) return, -1 for wait forever or positive for a limited wait. |
| 13 | + |
| 14 | +As per the POSIX specification, `poll` always indicates that ordinary files (as opposed to devices) are readable and writable. |
| 15 | + |
| 16 | +### Poll reference |
| 17 | + |
| 18 | +[](https://os.mbed.com/docs/mbed-os/v5.11/mbed-os-api-doxy/group__platform__poll.html) |
| 19 | + |
| 20 | +### Poll example |
| 21 | + |
| 22 | +``` |
| 23 | +// Transfer bidirectional data between two ports, acting as a virtual link. |
| 24 | +// poll() is used to monitor both ports for input. |
| 25 | +#include "mbed.h" |
| 26 | +
|
| 27 | +// Pins for each port are specified using mbed_app.json. Assume no flow control. |
| 28 | +// (If there were flow control, being blocked by it could break the implementation, |
| 29 | +// as you would stop reading input in the opposite direction). |
| 30 | +UARTSerial device1(MBED_CONF_APP_UART1_TX, MBED_CONF_APP_UART1_RX); |
| 31 | +UARTSerial device2(MBED_CONF_APP_UART2_TX, MBED_CONF_APP_UART2_RX); |
| 32 | +
|
| 33 | +// Precondition: "in" is readable |
| 34 | +static void copy_some(FileHandle *out, FileHandle *in) |
| 35 | +{ |
| 36 | + // To ensure performance, try to read multiple bytes at once, |
| 37 | + // but don't expect to read many in practice. |
| 38 | + char buffer[32]; |
| 39 | +
|
| 40 | + // Despite the FileHandle being in its default blocking mode, |
| 41 | + // read() must return immediately with between 1-32 bytes, as |
| 42 | + // you've already checked that `in` is ready with poll() |
| 43 | + ssize_t read = in->read(buffer, sizeof buffer); |
| 44 | + if (read <= 0) { |
| 45 | + error("Input error"); |
| 46 | + } |
| 47 | +
|
| 48 | + // Write everything out. Assuming output port is same speed as input, |
| 49 | + // and no flow control, this may block briefly but not significantly. |
| 50 | + ssize_t written = out->write(buffer, read); |
| 51 | + if (written < read) { |
| 52 | + error("Output error"); |
| 53 | + } |
| 54 | +} |
| 55 | +
|
| 56 | +int main() |
| 57 | +{ |
| 58 | + char buffer[32]; |
| 59 | + pollfh fds[2]; |
| 60 | +
|
| 61 | + fds[0].fh = &device1; |
| 62 | + fds[0].events = POLLIN; |
| 63 | + fds[1].fh = &device2; |
| 64 | + fds[1].events = POLLIN; |
| 65 | +
|
| 66 | + while (1) { |
| 67 | + // Block indefinitely until either of the 2 ports is readable (or has an error) |
| 68 | + poll(fds, 2, -1); |
| 69 | +
|
| 70 | + // Transfer some data in either or both directions |
| 71 | + if (fds[0].revents) { |
| 72 | + copy_some(fds[1].fh, fds[0].fh); |
| 73 | + } |
| 74 | + if (fds[1].revents) { |
| 75 | + copy_some(fds[0].fh, fds[1].fh); |
| 76 | + } |
| 77 | + } |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | +### Related content |
| 82 | + |
| 83 | +- [FileHandle](filehandle.html). |
0 commit comments