Polling file descriptors

Waiting for events on file descriptors

Every EVL core element is represented by a device file accessible in the /dev/evl hierarchy, and requests can be sent to any of those elements by writing to common file descriptors obtained on the corresponding files. Conversely, information is returned to the caller by reading from those file descriptors. EVL applications can poll for out-of-band events occurring on a set of file descriptors opened on elements, just like in-band applications can use poll(2) with other files.

To access the out-of-band polling services, an application first needs to obtain a file descriptor on a new polling set by a call to (#evl_new_poll). Such descriptor is an access point for registering other file descriptors to monitor, then sensing events occurring on them. evl_poll() or evl_timedpoll() fill an array of structures indicating which events have been received on each notified file descriptor. The type of this structure is as follows:

struct evl_poll_event {
	__u32 fd;
	__u32 events;
};

Applications can wait for any event which poll(2) can monitor such as POLLIN, POLLOUT, POLLRDNORM, POLLWRNORM and so on. Which event can occur on a given file descriptor is defined by the out-of-band driver managing the file it refers to.

Pollable elements
Semaphore
Event flag group
Timer
Proxy
Cross-buffer

Polling services

int evl_new_poll(void)

This call creates a polling set, returning a file descriptor representing the new object upon success. There is no arbitrary limit on the number of polling sets an application can create, which is only limited to the available system resources.

evl_new_poll() returns the file descriptor of the newly created polling set on success. Otherwise, a negated error code is returned:

  • -EMFILE The per-process limit on the number of open file descriptors has been reached.

  • -ENFILE The system-wide limit on the total number of open files has been reached.

  • -ENOMEM No memory available.

  • -ENXIO The EVL library is not initialized for the current process. Such initialization happens implicitly when evl_attach_self() is called by any thread of your process, or by explicitly calling evl_init(). You have to bootstrap the library services in a way or another before creating an EVL polling set.


int evl_add_pollfd(int efd, int newfd, unsigned int events)

Adds a file descriptor to a polling set. This service registers the newfd file descriptor for being polled for events by the efd polling set.

  • efd

    The file descriptor of a polling set obtained by a previous call to evl_new_poll().

  • newfd

    A file descriptor to monitor for events. Once newfd is added to the polling set, it becomes a source of events which is monitored when reading from efd. You can add as many file descriptor as you need to a polling set in order to perform synchronous I/O multiplexing over multiple data sources or sinks.

  • events

    A bitmask representing the set of events to monitor for newfd. These events are common to the in-band poll(2) interface. POLLERR and POLLHUP are always implicitly polled, even if they are not mentioned in events. POLLNVAL cannot be awaited for. Which event is meaningful in the context of the call depends on the driver managing the file, which defines the logic for raising them. For instance, if newfd refers to an EVL semaphore, you could monitor POLLIN and POLLRDNORM, no other event would occur for this type of file.

  • evl_add_pollfd() returns zero on success. Otherwise, a negated error code is returned:

    • -EBADF efd is not a valid file descriptor referring to an EVL polling set.

    • -EBADF newfd is not a valid file descriptor to an EVL file. Note that you cannot register a file descriptor referring to a common file (i.e. managed by an in-band driver) into an EVL polling set. An EVL file is created by out-of-band drivers for referring to resources which can be accessed from the out-of-band execution stage.

    • -ELOOP Adding newfd to the polling set would lead to a cyclic dependency (such as newfd referring to the polling set).

    • -ENOMEM No memory available.


    int evl_del_pollfd(int efd, int delfd)

    Removes a file descriptor from a polling set. As a result, reading this polling set does not monitor delfd anymore. This change applies to subsequent calls to evl_poll() or evl_timedpoll() for such set; ongoing waits are not affected.

  • efd

    The file descriptor of a polling set obtained by a previous call to evl_new_poll().

  • delfd

    The file descriptor to stop monitoring for events. This descriptor should have been registered by an earlier call to evl_add_pollfd().

  • evl_del_pollfd() returns zero on success. Otherwise, a negated error code is returned:

    • -EBADF efd is not a valid file descriptor referring to an EVL polling set.

    • -ENOENT delfd is not a file descriptor present into the polling set referred to by efd.


    int evl_mod_pollfd(int efd, int modfd, unsigned int events)

    Modifies the events being monitored for a file descriptor already registered in a polling set. This change applies to subsequent calls to evl_poll() or evl_timedpoll() for such set; ongoing waits are not affected.

  • efd

    The file descriptor of a polling set obtained by a previous call to evl_new_poll().

  • modfd

    The file descriptor to update the event mask for. This descriptor should have been registered by an earlier call to evl_add_pollfd().

  • evl_mod_pollfd() returns zero on success. Otherwise, a negated error code is returned:

    • -EBADF efd is not a valid file descriptor referring to an EVL polling set.

    • -ENOENT pollfd is not a file descriptor present into the polling set referred to by efd.


    int evl_poll(int efd, struct evl_poll_event *pollset, int nrset)

    Waits for events on the file descriptors present in the polling set referred to by efd.

  • efd

    The file descriptor of a polling set obtained by a previous call to evl_new_poll().

  • pollset

    The start of an array of structures of type evl_poll_event containing the set of file descriptors which have received at least one event when the call returns.

  • nrset

    The number of structures in the pollset array. If zero, evl_poll() returns immediately with a zero count.

  • On success, evl_poll() returns the count of file descriptors from the polling set for which an event is pending, each of them will appear in a evl_poll_event entry in pollset. Otherwise, a negated error code is returned:

    • -EBADF efd is not a valid file descriptor referring to an EVL polling set.

    • -EINVAL nrset is negative.

    • -EAGAIN fd is marked as non-blocking (O_NONBLOCK), and no file descriptor from the polling set has any event pending.

    • -EFAULT pollset points to invalid memory.


    int evl_timedpoll(int efd, struct evl_poll_event *pollset, int nrset, struct timespec *timeout)

    This call is a variant of evl_poll() which allows specifying a timeout on the polling operation, so that the caller is unblocked after a specified delay sleeping without receiving any event.

  • efd

    The file descriptor of a polling set obtained by a previous call to evl_new_poll().

  • pollset

    The start of an array of structures of type evl_poll_event containing the set of file descriptors which have received at least one event when the call returns.

  • nrset

    The number of structures in the pollset array. If zero, evl_poll() returns immediately with a zero count.

  • timeout

    A time limit to wait for any event to be notified before the call returns on error. Timeouts are always based on the built-in EVL_CLOCK_MONOTONIC clock. If both the tv_sec and tv_nsec members of timeout are set to zero, evl_timedpoll() behaves identically to evl_poll().

  • On success, evl_timedpoll() returns the count of file descriptors from the polling set for which an event is pending, each of them will appear in a evl_poll_event entry in pollset. Otherwise, a negated error code is returned:

    • -EBADF efd is not a valid file descriptor referring to an EVL polling set.

    • -EINVAL nrset is negative.

    • -EFAULT pollset or timeout point to invalid memory.

    • -EINVAL any of tv_sec or tv_nsec in timeout is invalid.

    • -ETIMEDOUT The timeout fired, after the amount of time specified by timeout.


    Last modified: Tue, 26 Nov 2019 18:03:02 CET