pollset_create, pollset_ctl, pollset_destroy, pollset_poll, and pollset_query Subroutines

Purpose

Check I/O status of multiple file descriptors.

Library

Standard C Library (libc.a)

Syntax

#include <sys/poll.h>
#include <sys/pollset.h>
#include <sys/fcntl.h>

pollset_t ps = pollset_create(int maxfd)
int rc = pollset_destroy(pollset_t ps)
int rc = pollset_ctl(pollset_t ps, struct poll_ctl *pollctl_array,
                             int array_length)
int rc = pollset_query(pollset_t ps, struct pollfd *pollfd_query)
int nfound = pollset_poll(pollset_t ps,
                                    struct pollfd *polldata_array,
                                    int array_length, int timeout)

Description

The pollset application programming interface (API) efficiently poll a large file descriptor set. This interface is best used when the file descriptor set is not frequently updated. The pollset subroutine can provide a significant performance enhancement over traditional select and poll APIs. Improvements are most visible when the number of events returned per poll operation is small in relation to the number of file descriptors polled.

The pollset API uses system calls to accomplish polling. A file descriptor set (or pollset) is established with a successful call to pollset_create. File descriptors and poll events are added, removed, or updated using the pollset_ctl subroutine. The pollset_poll subroutine is called to perform the poll operation. A pollset_query subroutine is called to query if a file descriptor is contained in the current poll set.

A pollset is established with a successful call to pollset_create. The pollset is initially empty following this system call. Each call to pollset_create creates a new and independent pollset. This can be useful to applications that monitor distinct sets of file descriptors. The maximum number of file descriptors that can belong to the pollset is specified by maxfd. If maxfd has a value of -1, the maximum number of file descriptors that can belong to the pollset is bound by OPEN_MAX as defined in <sys/limits.h> (the AIX® limit of open file descriptors per process). AIX imposes a system-wide limit of 245025 active pollsets at one time. Upon failure, this system call returns -1 with errno set appropriately. Upon success, a pollset ID of type pollset_t is returned:
       typedef int pollset_t

The pollset ID must not be altered by the application. The pollset API verifies that the ID is not -1. In addition, the process ID of the application must match the process ID stored at pollset creation time.

A pollset is destroyed with a successful call to pollset_destroy. Upon success, this system call returns 0. Upon failure, the pollset_destroy subroutine returns -1 with errno set to the appropriate code. An errno of EINVAL indicates an invalid pollset ID.

File descriptors must be added to the pollset with the pollset_ctl subroutine before they can be monitored. An array of poll_ctl structures is passed to pollset_ctl through pollctl_array:
       struct poll_ctl {
              short cmd;
              short events;
              int fd;
              
       }

Each poll_ctl structure contains an fd, events, and cmd field. The fd field defines the file descriptor to operate on. The events field contains events of interest. When cmd is PS_ADD, the pollset_ctl call adds a valid open file descriptor to the pollset. If a file descriptor is already in the pollset, PS_ADD causes pollset_ctl to return an error. When cmd is PS_MOD and the file descriptor is already in the pollset, bits in the events field are added (ORed) to the monitored events. If the file descriptor is not already in the pollset, PS_MOD adds a valid open file descriptor to the pollset.

Although poll events can be added by specifying an existing file descriptor, the file descriptor must be removed and then added again to remove an event. When cmd is PS_DELETE and the file descriptor is already in the pollset, pollset_ctl removes the file descriptor from the pollset. If the file descriptor is not already in the pollset, then PS_DELETE causes pollset_ctl to return an error.

The pollset_query interface can be used to determine information about a file descriptor with respect to the pollset. If the file descriptor is in the pollset, pollset_query returns 1 and events is set to the currently monitored events.

The pollset_poll subroutine determines which file descriptors in the pollset that have events pending. The polldata_array parameter contains a buffer address where pollfd structures are returned for file descriptors that have pending events. The number of events returned by a poll is limited by array_length. The timeout parameter specifies the amount of time to wait if no events are pending. Setting timeout to 0 guarantees that the pollset_poll subroutine returns immediately. Setting timeout to -1 specifies an infinite timeout. Other nonzero positive values specify the time to wait in milliseconds.

When events are returned from a pollset_poll operation, each pollfd structure contains an fd member with the file descriptor set, an events member with the requested events, and an revents member with the events that have occurred.

A single pollset can be accessed by multiple threads in a multithreaded process. When multiple threads are polling one pollset and an event occurs for a file descriptor, only one thread can be prompted to receive the event. After a file descriptor is returned to a thread, new events will not be generated until the next pollset_poll call. This behavior prevents all threads from being prompted on each event. Multiple threads can perform pollset_poll operations at one time, but modifications to the pollset require exclusive access. A thread that tries to modify the pollset is blocked until all threads currently in poll operations have exited pollset_poll. In addition, a thread calling pollset_destroy is blocked until all threads have left the other system calls (pollset_ctl, pollset_query, and pollset_poll).

A process can call fork after calling pollset_create. The child process will already have a pollset ID per pollset, but pollset_destroy, pollset_ctl, pollset_query, and pollset_poll operations will fail with an errno value of EACCES.

After a file descriptor is added to a pollset, the file descriptor will not be removed until a pollset_ctl call with the cmd of PS_DELETE is executed. The file descriptor remains in the pollset even if the file descriptor is closed. A pollset_poll operation on a pollset containing a closed file descriptor returns a POLLNVAL event for that file descriptor. If the file descriptor is later allocated to a new object, the new object will be polled on future pollset_poll calls.

Parameters

Item Description
array_length Specifies the length of the array parameters.
maxfd Specifies the maximum number of file descriptors that can belong to the pollset.
pollctl_array The pointer to an array of poll_ctl structures that describes the file descriptors (through the pollfd structure) and the unique operation to perform on each file descriptor (add, remove, or modify).
polldata_array Returns the requested events that have occurred on the pollset.
pollfd_query Points to a file descriptor that might or might not belong to the pollset. If it belongs to the pollset, then the requested events field of this parameter is updated to reflect what is currently being monitored for this file descriptor.
ps Specifies the pollset ID.
timeout Specifies the amount of time in milliseconds to wait for any monitored events to occur. A value of -1 blocks until some monitored event occurs.

Return Values

Upon success, the pollset_destroy returns 0. Upon failure, the pollset_destroy subroutine returns -1 with errno set to the appropriate code.

Upon success, the pollset_create subroutine returns a pollset ID of type pollset_t. Upon failure, this system call returns -1 with errno set appropriately.

Upon success, pollset_ctl returns 0. Upon failure, pollset_ctl returns the 0-based problem element number of the pollctl_array (for example, 2 is returned for element 3). If the first element is the problem element, or some other error occurs prior to processing the array of elements, -1 is returned and errno is set to the appropriate code. The calling application must acknowledge that elements in the array prior to the problem element were successfully processed and should attempt to call pollset_ctl again with the elements of pollctl_array beyond the problematic element.

If a file descriptor is not a member of the pollset, pollset_query returns 0. If the file descriptor is in the pollset, pollset_query returns 1 and events is set to the currently monitored events. If an error occurs after there is an attempt to determine if the file descriptor is a member of the pollset, then pollset_query returns -1 with errno set to the appropriate return code.

The pollset_poll subroutine returns the number of file descriptors on which requested events occurred. When no requested events occurred on any of the file descriptors, 0 is returned. A value of -1 is returned when an error occurs and errno is set to the appropriate code.

Error Codes

Item Description
EACCES Process does not have permission to access a pollset.
EAGAIN System resource temporarily not available.
EFAULT Address supplied was not valid.
EINTR A signal was received during the system call.
EINVAL Invalid parameter.
ENOMEM Insufficient system memory available.
ENOSPC Maximum number of pollsets in use.
EPERM Process does not have permission to create a pollset.