mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-25 22:30:51 +08:00
131 lines
4.8 KiB
Plaintext
131 lines
4.8 KiB
Plaintext
= zmq_poll(3)
|
|
|
|
|
|
== NAME
|
|
zmq_ppoll - input/output multiplexing with signal mask
|
|
|
|
|
|
== SYNOPSIS
|
|
|
|
*int zmq_ppoll (zmq_pollitem_t '*items', int 'nitems', long 'timeout', const sigset_t '*sigmask');*
|
|
|
|
|
|
== DESCRIPTION
|
|
The relationship between _zmq_poll()_ and _zmq_ppoll()_ is analogous to the
|
|
relationship between poll(2) and ppoll(2) and between select(2) and
|
|
pselect(2): _zmq_ppoll()_ allows an application to safely wait until either a
|
|
file descriptor becomes ready or until a signal is caught.
|
|
|
|
When using _zmq_ppoll()_ with 'sigmask' set to NULL, its behavior is identical
|
|
to that of _zmq_poll()_. See xref:zmq_poll.adoc[zmq_poll] for more on this.
|
|
|
|
To make full use of _zmq_ppoll()_, a non-NULL pointer to a signal mask must be
|
|
constructed and passed to 'sigmask'. See sigprocmask(2) for more details. When
|
|
this is done, inside the actual _ppoll()_ (or _pselect()_, see note below)
|
|
system call, an atomic operation consisting of three steps is performed:
|
|
1. The current signal mask is replaced by the one pointed to by 'sigmask'.
|
|
2. The actual _poll()_ call is done.
|
|
3. The original signal mask is restored.
|
|
Because these operations are done atomically, there is no opportunity for race
|
|
conditions in between the calls changing the signal mask and the poll/select
|
|
system call. This means that only during this (atomic) call, we can unblock
|
|
certain signals, so that they can be handled *at that time only*, not outside
|
|
of the call. This means that effectively, we extend our poller into a function
|
|
that not only watches sockets for changes, but also watches the "POSIX signal
|
|
socket" for incoming signals. At other times, these signals will be blocked,
|
|
and we will not have to deal with interruptions in system calls at these other
|
|
times.
|
|
|
|
NOTE: The _zmq_ppoll()_ function may be implemented or emulated using operating
|
|
system interfaces other than _ppoll()_, and as such may be subject to the
|
|
limits of those interfaces in ways not defined in this documentation.
|
|
|
|
NOTE: There is no _ppoll_ or _pselect_ on Windows, so _zmq_ppoll()_ is not
|
|
supported in Windows builds. It is still callable, but its 'sigmask' has void
|
|
pointer type (because 'sigset_t' is also not available on Windows) and
|
|
_zmq_ppoll()_ will return with an error (see error section below).
|
|
|
|
== THREAD SAFETY
|
|
The *zmq_pollitem_t* array must only be used by the thread which
|
|
will/is calling _zmq_ppoll_.
|
|
|
|
If a socket is contained in multiple *zmq_pollitem_t* arrays, each owned by a
|
|
different thread, the socket itself needs to be thead-safe (Server, Client, ...).
|
|
Otherwise, behaviour is undefined.
|
|
|
|
|
|
== RETURN VALUE
|
|
Upon successful completion, the _zmq_ppoll()_ function shall return the number
|
|
of *zmq_pollitem_t* structures with events signaled in 'revents' or `0` if no
|
|
events have been signaled. Upon failure, _zmq_ppoll()_ shall return `-1` and set
|
|
'errno' to one of the values defined below.
|
|
|
|
|
|
== ERRORS
|
|
*ETERM*::
|
|
At least one of the members of the 'items' array refers to a 'socket' whose
|
|
associated 0MQ 'context' was terminated.
|
|
*EFAULT*::
|
|
The provided 'items' was not valid (NULL).
|
|
*EINTR*::
|
|
The operation was interrupted by delivery of a signal before any events were
|
|
available.
|
|
*EINTR*::
|
|
The operation was interrupted by delivery of a signal before any events were
|
|
available.
|
|
*ENOTSUP*::
|
|
_zmq_ppoll()_ was not activated in this build.
|
|
|
|
|
|
== EXAMPLE
|
|
.Polling indefinitely for input events on both a 0MQ socket and a standard socket.
|
|
See the _example section_ of xref:zmq_poll.adoc[zmq_poll] One only needs to replace
|
|
the _zmq_poll_ call with _zmq_ppoll_ and add a _NULL_ argument for the 'sigmask'
|
|
parameter.
|
|
|
|
.Handle SIGTERM during _zmq_ppoll_ (and block it otherwise).
|
|
----
|
|
// simple global signal handler for SIGTERM
|
|
static bool sigterm_received = false;
|
|
void handle_sigterm (int signum) {
|
|
sigterm_received = true;
|
|
}
|
|
|
|
// set up signal mask and install handler for SIGTERM
|
|
sigset_t sigmask, sigmask_without_sigterm;
|
|
sigemptyset(&sigmask);
|
|
sigaddset(&sigmask, SIGTERM);
|
|
sigprocmask(SIG_BLOCK, &sigmask, &sigmask_without_sigterm);
|
|
struct sigaction sa;
|
|
memset(&sa, '\0', sizeof(sa));
|
|
sa.sa_handler = handle_sigterm;
|
|
|
|
// poll
|
|
zmq_pollitem_t items [1];
|
|
// Just one item, which refers to 0MQ socket 'socket' */
|
|
items[0].socket = socket;
|
|
items[0].events = ZMQ_POLLIN;
|
|
// Poll for events indefinitely, but also exit on SIGTERM
|
|
int rc = zmq_poll (items, 2, -1, &sigmask_without_sigterm);
|
|
if (rc < 0 && errno == EINTR && sigterm_received) {
|
|
// do your SIGTERM business
|
|
} else {
|
|
// do your non-SIGTERM error handling
|
|
}
|
|
----
|
|
|
|
|
|
== SEE ALSO
|
|
* xref:zmq_poll.adoc[zmq_poll]
|
|
* xref:zmq_socket.adoc[zmq_socket]
|
|
* xref:zmq_send.adoc[zmq_send]
|
|
* xref:zmq_recv.adoc[zmq_recv]
|
|
* xref:zmq.adoc[zmq]
|
|
|
|
Your operating system documentation for the _poll()_ system call.
|
|
|
|
|
|
== AUTHORS
|
|
This page was written by the 0MQ community. To make a change please
|
|
read the 0MQ Contribution Policy at <https://zeromq.org/how-to-contribute/>.
|