1ZLOOP(3) CZMQ Manual ZLOOP(3)
2
3
4
6 zloop - Class for event-driven reactor
7
9 // This is a stable class, and may not change except for emergencies. It
10 // is provided in stable builds.
11 // Callback function for reactor socket activity
12 typedef int (zloop_reader_fn) (
13 zloop_t *loop, zsock_t *reader, void *arg);
14
15 // Callback function for reactor events (low-level)
16 typedef int (zloop_fn) (
17 zloop_t *loop, zmq_pollitem_t *item, void *arg);
18
19 // Callback for reactor timer events
20 typedef int (zloop_timer_fn) (
21 zloop_t *loop, int timer_id, void *arg);
22
23 // Create a new zloop reactor
24 CZMQ_EXPORT zloop_t *
25 zloop_new (void);
26
27 // Destroy a reactor
28 CZMQ_EXPORT void
29 zloop_destroy (zloop_t **self_p);
30
31 // Register socket reader with the reactor. When the reader has messages,
32 // the reactor will call the handler, passing the arg. Returns 0 if OK, -1
33 // if there was an error. If you register the same socket more than once,
34 // each instance will invoke its corresponding handler.
35 CZMQ_EXPORT int
36 zloop_reader (zloop_t *self, zsock_t *sock, zloop_reader_fn handler, void *arg);
37
38 // Cancel a socket reader from the reactor. If multiple readers exist for
39 // same socket, cancels ALL of them.
40 CZMQ_EXPORT void
41 zloop_reader_end (zloop_t *self, zsock_t *sock);
42
43 // Configure a registered reader to ignore errors. If you do not set this,
44 // then readers that have errors are removed from the reactor silently.
45 CZMQ_EXPORT void
46 zloop_reader_set_tolerant (zloop_t *self, zsock_t *sock);
47
48 // Register low-level libzmq pollitem with the reactor. When the pollitem
49 // is ready, will call the handler, passing the arg. Returns 0 if OK, -1
50 // if there was an error. If you register the pollitem more than once, each
51 // instance will invoke its corresponding handler. A pollitem with
52 // socket=NULL and fd=0 means 'poll on FD zero'.
53 CZMQ_EXPORT int
54 zloop_poller (zloop_t *self, zmq_pollitem_t *item, zloop_fn handler, void *arg);
55
56 // Cancel a pollitem from the reactor, specified by socket or FD. If both
57 // are specified, uses only socket. If multiple poll items exist for same
58 // socket/FD, cancels ALL of them.
59 CZMQ_EXPORT void
60 zloop_poller_end (zloop_t *self, zmq_pollitem_t *item);
61
62 // Configure a registered poller to ignore errors. If you do not set this,
63 // then poller that have errors are removed from the reactor silently.
64 CZMQ_EXPORT void
65 zloop_poller_set_tolerant (zloop_t *self, zmq_pollitem_t *item);
66
67 // Register a timer that expires after some delay and repeats some number of
68 // times. At each expiry, will call the handler, passing the arg. To run a
69 // timer forever, use 0 times. Returns a timer_id that is used to cancel the
70 // timer in the future. Returns -1 if there was an error.
71 CZMQ_EXPORT int
72 zloop_timer (zloop_t *self, size_t delay, size_t times, zloop_timer_fn handler, void *arg);
73
74 // Cancel a specific timer identified by a specific timer_id (as returned by
75 // zloop_timer).
76 CZMQ_EXPORT int
77 zloop_timer_end (zloop_t *self, int timer_id);
78
79 // Register a ticket timer. Ticket timers are very fast in the case where
80 // you use a lot of timers (thousands), and frequently remove and add them.
81 // The main use case is expiry timers for servers that handle many clients,
82 // and which reset the expiry timer for each message received from a client.
83 // Whereas normal timers perform poorly as the number of clients grows, the
84 // cost of ticket timers is constant, no matter the number of clients. You
85 // must set the ticket delay using zloop_set_ticket_delay before creating a
86 // ticket. Returns a handle to the timer that you should use in
87 // zloop_ticket_reset and zloop_ticket_delete.
88 CZMQ_EXPORT void *
89 zloop_ticket (zloop_t *self, zloop_timer_fn handler, void *arg);
90
91 // Reset a ticket timer, which moves it to the end of the ticket list and
92 // resets its execution time. This is a very fast operation.
93 CZMQ_EXPORT void
94 zloop_ticket_reset (zloop_t *self, void *handle);
95
96 // Delete a ticket timer. We do not actually delete the ticket here, as
97 // other code may still refer to the ticket. We mark as deleted, and remove
98 // later and safely.
99 CZMQ_EXPORT void
100 zloop_ticket_delete (zloop_t *self, void *handle);
101
102 // Set the ticket delay, which applies to all tickets. If you lower the
103 // delay and there are already tickets created, the results are undefined.
104 CZMQ_EXPORT void
105 zloop_set_ticket_delay (zloop_t *self, size_t ticket_delay);
106
107 // Set hard limit on number of timers allowed. Setting more than a small
108 // number of timers (10-100) can have a dramatic impact on the performance
109 // of the reactor. For high-volume cases, use ticket timers. If the hard
110 // limit is reached, the reactor stops creating new timers and logs an
111 // error.
112 CZMQ_EXPORT void
113 zloop_set_max_timers (zloop_t *self, size_t max_timers);
114
115 // Set verbose tracing of reactor on/off. The default verbose setting is
116 // off (false).
117 CZMQ_EXPORT void
118 zloop_set_verbose (zloop_t *self, bool verbose);
119
120 // By default the reactor stops if the process receives a SIGINT or SIGTERM
121 // signal. This makes it impossible to shut-down message based architectures
122 // like zactors. This method lets you switch off break handling. The default
123 // nonstop setting is off (false).
124 CZMQ_EXPORT void
125 zloop_set_nonstop (zloop_t *self, bool nonstop);
126
127 // Start the reactor. Takes control of the thread and returns when the 0MQ
128 // context is terminated or the process is interrupted, or any event handler
129 // returns -1. Event handlers may register new sockets and timers, and
130 // cancel sockets. Returns 0 if interrupted, -1 if canceled by a handler.
131 CZMQ_EXPORT int
132 zloop_start (zloop_t *self);
133
134 // Self test of this class.
135 CZMQ_EXPORT void
136 zloop_test (bool verbose);
137
138 Please add '@interface' section in './../src/zloop.c'.
139
141 The zloop class provides an event-driven reactor pattern. The reactor
142 handles zmq_pollitem_t items (pollers or writers, sockets or fds), and
143 once-off or repeated timers. Its resolution is 1 msec. It uses a
144 tickless timer to reduce CPU interrupts in inactive processes.
145
146 Please add @discuss section in ./../src/zloop.c.
147
149 From zloop_test method.
150
151 // Create two PAIR sockets and connect over inproc
152 zsock_t *output = zsock_new (ZMQ_PAIR);
153 assert (output);
154 zsock_bind (output, "inproc://zloop.test");
155
156 zsock_t *input = zsock_new (ZMQ_PAIR);
157 assert (input);
158 zsock_connect (input, "inproc://zloop.test");
159
160 zloop_t *loop = zloop_new ();
161 assert (loop);
162 zloop_set_verbose (loop, verbose);
163
164 // Create a timer that will be cancelled
165 int timer_id = zloop_timer (loop, 1000, 1, s_timer_event, NULL);
166 zloop_timer (loop, 5, 1, s_cancel_timer_event, &timer_id);
167
168 // After 20 msecs, send a ping message to output3
169 zloop_timer (loop, 20, 1, s_timer_event, output);
170
171 // Set up some tickets that will never expire
172 zloop_set_ticket_delay (loop, 10000);
173 void *ticket1 = zloop_ticket (loop, s_timer_event, NULL);
174 void *ticket2 = zloop_ticket (loop, s_timer_event, NULL);
175 void *ticket3 = zloop_ticket (loop, s_timer_event, NULL);
176
177 // When we get the ping message, end the reactor
178 rc = zloop_reader (loop, input, s_socket_event, NULL);
179 assert (rc == 0);
180 zloop_reader_set_tolerant (loop, input);
181 zloop_start (loop);
182
183 zloop_ticket_delete (loop, ticket1);
184 zloop_ticket_delete (loop, ticket2);
185 zloop_ticket_delete (loop, ticket3);
186
187 // Check whether loop properly ignores zsys_interrupted flag
188 // when asked to
189 zloop_destroy (&loop);
190 loop = zloop_new ();
191
192 bool timer_event_called = false;
193 zloop_timer (loop, 1, 1, s_timer_event3, &timer_event_called);
194
195 zsys_interrupted = 1;
196 zloop_start (loop);
197 // zloop returns immediately without giving any handler a chance to run
198 assert (!timer_event_called);
199
200 zloop_set_nonstop (loop, true);
201 zloop_start (loop);
202 // zloop runs the handler which will terminate the loop
203 assert (timer_event_called);
204 zsys_interrupted = 0;
205
206 // Check if reader removed in timer is not called
207 zloop_destroy (&loop);
208 loop = zloop_new ();
209
210 bool socket_event_called = false;
211 zloop_reader (loop, output, s_socket_event1, &socket_event_called);
212 zloop_timer (loop, 0, 1, s_timer_event5, output);
213
214 zstr_send (input, "PING");
215
216 zloop_start (loop);
217 assert (!socket_event_called);
218
219 // cleanup
220 zloop_destroy (&loop);
221 assert (loop == NULL);
222
223 zsock_destroy (&input);
224 zsock_destroy (&output);
225
226 #if defined (__WINDOWS__)
227 zsys_shutdown();
228 #endif
229
230
232 The czmq manual was written by the authors in the AUTHORS file.
233
235 Main web site:
236
237 Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>
238
240 Copyright (c) the Contributors as noted in the AUTHORS file. This file
241 is part of CZMQ, the high-level C binding for 0MQ:
242 http://czmq.zeromq.org. This Source Code Form is subject to the terms
243 of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
244 distributed with this file, You can obtain one at
245 http://mozilla.org/MPL/2.0/. LICENSE included with the czmq
246 distribution.
247
249 1. zeromq-dev@lists.zeromq.org
250 mailto:zeromq-dev@lists.zeromq.org
251
252
253
254CZMQ 4.1.1 01/31/2019 ZLOOP(3)