'\" t .\" Title: zloop .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 03/02/2024 .\" Manual: CZMQ Manual .\" Source: CZMQ 4.2.1 .\" Language: English .\" .TH "ZLOOP" "3" "03/02/2024" "CZMQ 4\&.2\&.1" "CZMQ Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" zloop \- Class for event\-driven reactor .SH "SYNOPSIS" .sp .nf // This is a stable class, and may not change except for emergencies\&. It // is provided in stable builds\&. // Callback function for reactor socket activity typedef int (zloop_reader_fn) ( zloop_t *loop, zsock_t *reader, void *arg); // Callback function for reactor events (low\-level) typedef int (zloop_fn) ( zloop_t *loop, zmq_pollitem_t *item, void *arg); // Callback for reactor timer events typedef int (zloop_timer_fn) ( zloop_t *loop, int timer_id, void *arg); // Create a new zloop reactor CZMQ_EXPORT zloop_t * zloop_new (void); // Destroy a reactor CZMQ_EXPORT void zloop_destroy (zloop_t **self_p); // Register socket reader with the reactor\&. When the reader has messages, // the reactor will call the handler, passing the arg\&. Returns 0 if OK, \-1 // if there was an error\&. If you register the same socket more than once, // each instance will invoke its corresponding handler\&. CZMQ_EXPORT int zloop_reader (zloop_t *self, zsock_t *sock, zloop_reader_fn handler, void *arg); // Cancel a socket reader from the reactor\&. If multiple readers exist for // same socket, cancels ALL of them\&. CZMQ_EXPORT void zloop_reader_end (zloop_t *self, zsock_t *sock); // Configure a registered reader to ignore errors\&. If you do not set this, // then readers that have errors are removed from the reactor silently\&. CZMQ_EXPORT void zloop_reader_set_tolerant (zloop_t *self, zsock_t *sock); // Register low\-level libzmq pollitem with the reactor\&. When the pollitem // is ready, will call the handler, passing the arg\&. Returns 0 if OK, \-1 // if there was an error\&. If you register the pollitem more than once, each // instance will invoke its corresponding handler\&. A pollitem with // socket=NULL and fd=0 means \*(Aqpoll on FD zero\*(Aq\&. CZMQ_EXPORT int zloop_poller (zloop_t *self, zmq_pollitem_t *item, zloop_fn handler, void *arg); // Cancel a pollitem from the reactor, specified by socket or FD\&. If both // are specified, uses only socket\&. If multiple poll items exist for same // socket/FD, cancels ALL of them\&. CZMQ_EXPORT void zloop_poller_end (zloop_t *self, zmq_pollitem_t *item); // Configure a registered poller to ignore errors\&. If you do not set this, // then poller that have errors are removed from the reactor silently\&. CZMQ_EXPORT void zloop_poller_set_tolerant (zloop_t *self, zmq_pollitem_t *item); // Register a timer that expires after some delay and repeats some number of // times\&. At each expiry, will call the handler, passing the arg\&. To run a // timer forever, use 0 times\&. Returns a timer_id that is used to cancel the // timer in the future\&. Returns \-1 if there was an error\&. CZMQ_EXPORT int zloop_timer (zloop_t *self, size_t delay, size_t times, zloop_timer_fn handler, void *arg); // Cancel a specific timer identified by a specific timer_id (as returned by // zloop_timer)\&. CZMQ_EXPORT int zloop_timer_end (zloop_t *self, int timer_id); // Register a ticket timer\&. Ticket timers are very fast in the case where // you use a lot of timers (thousands), and frequently remove and add them\&. // The main use case is expiry timers for servers that handle many clients, // and which reset the expiry timer for each message received from a client\&. // Whereas normal timers perform poorly as the number of clients grows, the // cost of ticket timers is constant, no matter the number of clients\&. You // must set the ticket delay using zloop_set_ticket_delay before creating a // ticket\&. Returns a handle to the timer that you should use in // zloop_ticket_reset and zloop_ticket_delete\&. CZMQ_EXPORT void * zloop_ticket (zloop_t *self, zloop_timer_fn handler, void *arg); // Reset a ticket timer, which moves it to the end of the ticket list and // resets its execution time\&. This is a very fast operation\&. CZMQ_EXPORT void zloop_ticket_reset (zloop_t *self, void *handle); // Delete a ticket timer\&. We do not actually delete the ticket here, as // other code may still refer to the ticket\&. We mark as deleted, and remove // later and safely\&. CZMQ_EXPORT void zloop_ticket_delete (zloop_t *self, void *handle); // Set the ticket delay, which applies to all tickets\&. If you lower the // delay and there are already tickets created, the results are undefined\&. CZMQ_EXPORT void zloop_set_ticket_delay (zloop_t *self, size_t ticket_delay); // Set hard limit on number of timers allowed\&. Setting more than a small // number of timers (10\-100) can have a dramatic impact on the performance // of the reactor\&. For high\-volume cases, use ticket timers\&. If the hard // limit is reached, the reactor stops creating new timers and logs an // error\&. CZMQ_EXPORT void zloop_set_max_timers (zloop_t *self, size_t max_timers); // Set verbose tracing of reactor on/off\&. The default verbose setting is // off (false)\&. CZMQ_EXPORT void zloop_set_verbose (zloop_t *self, bool verbose); // By default the reactor stops if the process receives a SIGINT or SIGTERM // signal\&. This makes it impossible to shut\-down message based architectures // like zactors\&. This method lets you switch off break handling\&. The default // nonstop setting is off (false)\&. CZMQ_EXPORT void zloop_set_nonstop (zloop_t *self, bool nonstop); // Start the reactor\&. Takes control of the thread and returns when the 0MQ // context is terminated or the process is interrupted, or any event handler // returns \-1\&. Event handlers may register new sockets and timers, and // cancel sockets\&. Returns 0 if interrupted, \-1 if canceled by a handler\&. CZMQ_EXPORT int zloop_start (zloop_t *self); // Self test of this class\&. CZMQ_EXPORT void zloop_test (bool verbose); Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zloop\&.c\*(Aq\&. .fi .SH "DESCRIPTION" .sp The zloop class provides an event\-driven reactor pattern\&. The reactor handles zmq_pollitem_t items (pollers or writers, sockets or fds), and once\-off or repeated timers\&. Its resolution is 1 msec\&. It uses a tickless timer to reduce CPU interrupts in inactive processes\&. .sp Please add \fI@discuss\fR section in \fI\&./\&.\&./src/zloop\&.c\fR\&. .SH "EXAMPLE" .PP \fBFrom zloop_test method\fR. .sp .if n \{\ .RS 4 .\} .nf // Create two PAIR sockets and connect over inproc zsock_t *output = zsock_new (ZMQ_PAIR); assert (output); zsock_bind (output, "inproc://zloop\&.test"); zsock_t *input = zsock_new (ZMQ_PAIR); assert (input); zsock_connect (input, "inproc://zloop\&.test"); zloop_t *loop = zloop_new (); assert (loop); zloop_set_verbose (loop, verbose); // Create a timer that will be cancelled int timer_id = zloop_timer (loop, 1000, 1, s_timer_event, NULL); zloop_timer (loop, 5, 1, s_cancel_timer_event, &timer_id); // After 20 msecs, send a ping message to output3 zloop_timer (loop, 20, 1, s_timer_event, output); // Set up some tickets that will never expire zloop_set_ticket_delay (loop, 10000); void *ticket1 = zloop_ticket (loop, s_timer_event, NULL); void *ticket2 = zloop_ticket (loop, s_timer_event, NULL); void *ticket3 = zloop_ticket (loop, s_timer_event, NULL); // When we get the ping message, end the reactor rc = zloop_reader (loop, input, s_socket_event, NULL); assert (rc == 0); zloop_reader_set_tolerant (loop, input); zloop_start (loop); zloop_ticket_delete (loop, ticket1); zloop_ticket_delete (loop, ticket2); zloop_ticket_delete (loop, ticket3); // Check whether loop properly ignores zsys_interrupted flag // when asked to zloop_destroy (&loop); loop = zloop_new (); bool timer_event_called = false; zloop_timer (loop, 1, 1, s_timer_event3, &timer_event_called); zsys_interrupted = 1; zloop_start (loop); // zloop returns immediately without giving any handler a chance to run assert (!timer_event_called); zloop_set_nonstop (loop, true); zloop_start (loop); // zloop runs the handler which will terminate the loop assert (timer_event_called); zsys_interrupted = 0; // Check if reader removed in timer is not called zloop_destroy (&loop); loop = zloop_new (); bool socket_event_called = false; zloop_reader (loop, output, s_socket_event1, &socket_event_called); zloop_timer (loop, 0, 1, s_timer_event5, output); zstr_send (input, "PING"); zloop_start (loop); assert (!socket_event_called); // cleanup zloop_destroy (&loop); assert (loop == NULL); zsock_destroy (&input); zsock_destroy (&output); #if defined (__WINDOWS__) zsys_shutdown(); #endif .fi .if n \{\ .RE .\} .sp .SH "AUTHORS" .sp The czmq manual was written by the authors in the AUTHORS file\&. .SH "RESOURCES" .sp Main web site: \m[blue]\fB\%\fR\m[] .sp Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> .SH "COPYRIGHT" .sp Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. .SH "NOTES" .IP " 1." 4 zeromq-dev@lists.zeromq.org .RS 4 \%mailto:zeromq-dev@lists.zeromq.org .RE