Skip site navigation (1)Skip section navigation (2)

  
 
  

home | help
ZLOOP(3)			   CZMQ Manual				ZLOOP(3)

NAME
     zloop - Class for event-driven reactor

SYNOPSIS
     //  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 'poll on FD zero'.
     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 '@interface' section in './../src/zloop.c'.

DESCRIPTION
     The  zloop class provides an event-driven reactor pattern. The reactor han-
     dles 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.

     Please add @discuss section in ./../src/zloop.c.

EXAMPLE
     From zloop_test method.

	 //  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

AUTHORS
     The czmq manual was written by the authors in the AUTHORS file.

RESOURCES
     Main web site:

     Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>

COPYRIGHT
     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  Li-
     cense, 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.

NOTES
      1. zeromq-dev@lists.zeromq.org
	 mailto:zeromq-dev@lists.zeromq.org

CZMQ 4.2.1			   08/27/2026				ZLOOP(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=zloop&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help