void zmonitor_test (bool verbose) { printf (" * zmonitor: "); if (verbose) printf ("\n"); // @selftest zctx_t *ctx = zctx_new (); bool result; void *sink = zsocket_new (ctx, ZMQ_PULL); zmonitor_t *sinkmon = zmonitor_new (ctx, sink, ZMQ_EVENT_LISTENING | ZMQ_EVENT_ACCEPTED); zmonitor_set_verbose (sinkmon, verbose); // Check sink is now listening int port_nbr = zsocket_bind (sink, "tcp://127.0.0.1:*"); assert (port_nbr != -1); result = s_check_event (sinkmon, ZMQ_EVENT_LISTENING); assert (result); void *source = zsocket_new (ctx, ZMQ_PUSH); zmonitor_t *sourcemon = zmonitor_new (ctx, source, ZMQ_EVENT_CONNECTED | ZMQ_EVENT_DISCONNECTED); zmonitor_set_verbose (sourcemon, verbose); zsocket_connect (source, "tcp://127.0.0.1:%d", port_nbr); // Check source connected to sink result = s_check_event (sourcemon, ZMQ_EVENT_CONNECTED); assert (result); // Check sink accepted connection result = s_check_event (sinkmon, ZMQ_EVENT_ACCEPTED); assert (result); // Destroy sink to trigger a disconnect event on the source // PH: disabled since this causes an access violation in // zmonitor_destroy as the socket is no longer valid. // zsocket_destroy (ctx, sink); // result = s_check_event (sourcemon, ZMQ_EVENT_DISCONNECTED); // assert (result); zmonitor_destroy (&sinkmon); zmonitor_destroy (&sourcemon); zctx_destroy (&ctx); // @end printf ("OK\n"); }
zmonitor_t * zmonitor_new (zctx_t *ctx, void *socket, int events) { zmonitor_t *self = (zmonitor_t *) zmalloc (sizeof (zmonitor_t)); assert (self); // Start background agent to connect to the inproc monitor socket assert (ctx); self->pipe = zthread_fork (ctx, s_agent_task, NULL); if (self->pipe) { self->socket = socket; // Register a monitor endpoint on the socket char *monitor_endpoint = (char *) zmalloc (100); sprintf (monitor_endpoint, "inproc://zmonitor-%p", self->socket); int rc = zmq_socket_monitor (self->socket, monitor_endpoint, events); assert (rc == 0); // Configure backend agent with monitor endpoint zstr_sendf (self->pipe, "%s", monitor_endpoint); free (monitor_endpoint); char *status = zstr_recv (self->pipe); if (strneq (status, "OK")) zmonitor_destroy (&self); zstr_free (&status); } else { free (self); self = NULL; } return self; }