nidas  v1.2-1520
Classes | Namespaces | Macros
Polled.h File Reference
#include <sys/poll.h>
#include <sys/epoll.h>

Go to the source code of this file.

Classes

class  nidas::core::Polled
 Interface for objects with a file descriptor, providing a virtual method to be called when system calls such as select, poll, or epoll indicate an event is pending on the file descriptor. More...
 

Namespaces

 nidas
 Root namespace for the NCAR In-Situ Data Acquisition Software.
 
 nidas::core
 The essential core classes of nidas.
 

Macros

#define POLL_EPOLL_ET   0 /* epoll edge-triggered */
 Enumeration of file descriptor polling methods supported by SensorHander. More...
 
#define POLL_EPOLL_LT   1 /* epoll level-triggered */
 
#define POLL_PSELECT   2 /* pselect */
 
#define POLL_POLL   3 /* poll/ppoll */
 
#define POLLING_METHOD   POLL_EPOLL_LT
 Select a POLLING_METHOD. More...
 
#define N_POLLIN   POLLIN
 epoll.h defines EPOLLIN, EPOLLERR, EPOLLHUP, EPOLLRDHUP poll.h defines POLLIN, POLLERR, POLLHUP, POLLRDHUP. More...
 
#define N_POLLERR   POLLERR
 
#define N_POLLHUP   POLLHUP
 
#define N_POLLRDHUP   POLLHUP
 

Macro Definition Documentation

#define N_POLLERR   POLLERR
#define N_POLLHUP   POLLHUP
#define N_POLLIN   POLLIN

epoll.h defines EPOLLIN, EPOLLERR, EPOLLHUP, EPOLLRDHUP poll.h defines POLLIN, POLLERR, POLLHUP, POLLRDHUP.

As of glibc 2.12 and 2.16 they have equal values.

Define local macros N_POLLIN, N_POLLERR, N_POLLHUP, N_POLLRDHUP from the poll.h values, so that code compiles with which ever system header file is used.

Referenced by nidas::core::RemoteSerialListener::handlePollEvents(), nidas::core::RemoteSerialConnection::handlePollEvents(), nidas::core::SensorHandler::PolledDSMSensor::handlePollEvents(), nidas::core::SensorHandler::NotifyPipe::handlePollEvents(), nidas::core::SensorHandler::run(), and nidas::core::SensorHandler::SensorHandler().

#define N_POLLRDHUP   POLLHUP
#define POLL_EPOLL_ET   0 /* epoll edge-triggered */

Enumeration of file descriptor polling methods supported by SensorHander.

Referenced by nidas::core::SensorHandler::run().

#define POLL_EPOLL_LT   1 /* epoll level-triggered */
#define POLL_POLL   3 /* poll/ppoll */
#define POLL_PSELECT   2 /* pselect */
#define POLLING_METHOD   POLL_EPOLL_LT

Select a POLLING_METHOD.

Also see discussion in SensorHandler.

The EPOLL methods are the most efficient, since the OS can cache the file descriptors of interest. They are not passed on each poll. The system is only notified when they change.

POLL_EPOLL_ET (edge-triggered) may also be a bit more efficient than POLL_EPOLL_LT (level-triggered), but there is one circumstance where it doesn't work in NIDAS.

Edge-triggering will only return a EPOLLIN event on a transition from no-data-available to data-available, so on an EPOLLIN, one must read all data available from a descriptor, using non-blocking IO, in order for an EPOLLIN event to occur again.

Read methods in NIDAS return a length of 0 on EAGAIN/EWOULDBLOCK, rather than an exception. So when using edge-triggering, one must do non-blocking reads on a descriptor until a return of 0. However with UDP sockets, incoming packets can have an actual length of 0 (we saw this on a NovAtel GPS), and so a read return of zero doesn't necesarily indicate there is no data left to read. Due to this bug, on receipt of a zero-length UDP packet using edge-triggering, NIDAS will cease to get EPOLLIN events on that socket.

Fixing this would require changing NIDAS reads to return an exception, or perhaps -1, on EAGAIN/EWOULDBLOCK. The possible gains of edge-triggering do not seem to be worth it, so we'll use level-triggering.

Referenced by nidas::core::SensorHandler::run().