void MessageProcessor::run() { for (;;) { // timeout is the time left until the next cron should execute. int64_t timeout = server_->computeTimeout(); if (timeout <= 0) { server_->ProcessCron(); continue; } // wait for incoming message or up to timeout, // i.e. stop polling in time for the next cron execution. if (zpoller_wait(zmqPoller_, timeout)) { processSocket(); continue; } if (zpoller_terminated(zmqPoller_)) { otErr << __FUNCTION__ << ": zpoller_terminated - process interrupted or" << " parent context destroyed\n"; break; } if (!zpoller_expired(zmqPoller_)) { otErr << __FUNCTION__ << ": zpoller_wait error\n"; // we do not want busy loop if something goes wrong Log::SleepMilliseconds(100); } } }
void drops_agent_main (void *args, zctx_t *ctx, void *pipe) { // Create agent instance to pass around s_agent_t *self = s_agent_new (ctx, pipe); if (!self) // Interrupted return; zstr_send (self->pipe, "OK"); // These are the sockets we will monitor for activity zpoller_t *poller = zpoller_new ( self->pipe, zyre_socket (self->zyre), NULL); while (!zpoller_terminated (poller)) { // Check directory once a second; this is a pretty nasty way of // doing it, but portable and simple. Later I'd like to use file // system monitoring library and get events back over a socket. void *which = zpoller_wait (poller, 1000); if (which == self->pipe) s_recv_from_api (self); else if (which == zyre_socket (self->zyre)) s_recv_from_zyre (self); if (self->terminated) break; s_check_directory (self); } zpoller_destroy (&poller); s_agent_destroy (&self); }
int maltcp_ctx_poller_wait( void *self, mal_poller_t *mal_poller, mal_endpoint_t **mal_endpoint, int timeout) { maltcp_poller_data_t *poller_data = (maltcp_poller_data_t *) mal_poller_get_poller_data(mal_poller); int rc = 0; clog_debug(maltcp_logger, "maltcp_ctx_poller_wait(%d)\n", timeout); zsock_t *which = (zsock_t *) zpoller_wait(poller_data->poller, timeout); if (zpoller_terminated(poller_data->poller)) { clog_debug(maltcp_logger, "maltcp_ctx_poller_wait: zpoller_terminated.\n"); return -1; } if (which) { maltcp_endpoint_data_t *endpoint_data = maltcp_get_endpoint(poller_data, which); if (endpoint_data != NULL) { *mal_endpoint = endpoint_data->mal_endpoint; clog_debug(maltcp_logger, "maltcp_ctx_poller_wait: data available for end-point %s\n", mal_endpoint_get_uri(*mal_endpoint)); } else { clog_error(maltcp_logger, "maltcp_ctx_poller_wait: cannot find corresponding end-point\n"); return -1; } } else { *mal_endpoint = NULL; } return rc; }
devio_err_e devio_poll_all_sm (devio_t *self) { devio_err_e err = DEVIO_SUCCESS; if (!self->poller) { err = DEVIO_ERR_UNINIT_POLLER; goto err_uninitialized_poller; } /* Wait up to 100 ms */ void *which = zpoller_wait (self->poller, DEVIO_POLLER_TIMEOUT); if (zpoller_expired (self->poller)) { /*DBE_DEBUG (DBG_DEV_IO | DBG_LVL_TRACE, "[dev_io_core:poll_all_sm] poller expired\n");*/ goto err_poller_expired; } if (zpoller_terminated (self->poller)) { /*DBE_DEBUG (DBG_DEV_IO | DBG_LVL_TRACE, "[dev_io_core:poll_all_sm] poller terminated\n");*/ err = DEVIO_ERR_TERMINATED; goto err_poller_terminated; } zmsg_t *recv_msg = zmsg_recv (which); /* Prepare the args structure */ zmq_server_args_t server_args = {.msg = &recv_msg, .reply_to = which}; err = _devio_do_smio_op (self, &server_args); err_poller_expired: err_poller_terminated: err_uninitialized_poller: return err; }
void zyre_node_engine (void *args, zctx_t *ctx, void *pipe) { // Create node instance to pass around zyre_node_t *self = zyre_node_new (ctx, pipe); if (!self) // Interrupted return; zsocket_signal (self->pipe); uint64_t reap_at = zclock_time () + REAP_INTERVAL; zpoller_t *poller = zpoller_new ( self->pipe, self->inbox, zbeacon_socket (self->beacon), NULL); while (!zpoller_terminated (poller)) { if (self->terminated) break; int timeout = (int) (reap_at - zclock_time ()); assert (timeout <= REAP_INTERVAL); if (timeout < 0) timeout = 0; void *which = zpoller_wait (poller, timeout); if (which == self->pipe) zyre_node_recv_api (self); else if (which == self->inbox) zyre_node_recv_peer (self); else if (which == zbeacon_socket (self->beacon)) zyre_node_recv_beacon (self); else if (zpoller_expired(poller)) { if (zclock_time () >= reap_at) { reap_at = zclock_time () + REAP_INTERVAL; // Ping all peers and reap any expired ones zhash_foreach (self->peers, zyre_node_ping_peer, self); } } else if (zpoller_terminated(poller)) break; else // This should never happen assert(false); } zpoller_destroy (&poller); zyre_node_destroy (&self); }
void zyre_node_actor (zsock_t *pipe, void *args) { // Create node instance to pass around zyre_node_t *self = zyre_node_new (pipe, args); if (!self) // Interrupted return; // Signal actor successfully initialized zsock_signal (self->pipe, 0); // Loop until the agent is terminated one way or another int64_t reap_at = zclock_time () + REAP_INTERVAL; while (!self->terminated) { int timeout = (int) (reap_at - zclock_time ()); if (timeout > REAP_INTERVAL) timeout = REAP_INTERVAL; else if (timeout < 0) timeout = 0; zsock_t *which = (zsock_t *) zpoller_wait (self->poller, timeout); if (which == self->pipe) zyre_node_recv_api (self); else if (which == self->inbox) zyre_node_recv_peer (self); else if (self->beacon && (void *) which == self->beacon) zyre_node_recv_beacon (self); else if (self->gossip && (zactor_t *) which == self->gossip) zyre_node_recv_gossip (self); else if (zpoller_terminated (self->poller)) break; // Interrupted, check before expired else if (zpoller_expired (self->poller)) { if (zclock_time () >= reap_at) { reap_at = zclock_time () + REAP_INTERVAL; // Ping all peers and reap any expired ones zhash_foreach (self->peers, (zhash_foreach_fn *) zyre_node_ping_peer, self); } } } zyre_node_destroy (&self); }
void zmonitor (zsock_t *pipe, void *args) { self_t *self = s_self_new (pipe, (zsock_t *) args); // Signal successful initialization zsock_signal (pipe, 0); while (!self->terminated) { zsock_t *which = zpoller_wait (self->poller, -1); if (which == self->pipe) s_self_handle_pipe (self); else if (which == self->sink) s_self_handle_sink (self); else if (zpoller_terminated (self->poller)) break; // Interrupted } s_self_destroy (&self); }
void mlm_stream_simple (zsock_t *pipe, void *args) { stream_engine_t *self = s_stream_engine_new (pipe, (zsock_t *) args); // Signal successful initialization zsock_signal (pipe, 0); while (!self->terminated) { zsock_t *which = (zsock_t *) zpoller_wait (self->poller, -1); if (which == self->cmdpipe) s_stream_engine_handle_command (self); else if (which == self->msgpipe) s_stream_engine_handle_message (self); else if (zpoller_terminated (self->poller)) break; // Interrupted } s_stream_engine_destroy (&self); }
void zauth (zsock_t *pipe, void *unused) { self_t *self = s_self_new (pipe); // Signal successful initialization zsock_signal (pipe, 0); while (!self->terminated) { zsock_t *which = (zsock_t *) zpoller_wait (self->poller, -1); if (which == self->pipe) s_self_handle_pipe (self); else if (which == self->handler) s_self_authenticate (self); else if (zpoller_terminated (self->poller)) break; // Interrupted } s_self_destroy (&self); }
static void s_agent_task (void *args, zctx_t *ctx, void *pipe) { // Create agent instance as we start this task agent_t *self = s_agent_new (ctx, pipe); if (!self) // Interrupted return; zpoller_t *poller = zpoller_new (self->pipe, self->handler, NULL); while (!zpoller_terminated (poller) && !self->terminated) { void *which = zpoller_wait (poller, -1); if (which == self->pipe) s_agent_handle_pipe (self); else if (which == self->handler) s_agent_authenticate (self); } // Done, free all agent resources zpoller_destroy (&poller); s_agent_destroy (&self); }
void upstream_actor (zsock_t *pipe, void *args) { upstream_t *self = s_upstream_new (pipe); zsock_signal (pipe, 0); while (!self->terminated) { if (self->connected) { zframe_t *content = s_upstream_create_content (self); zframe_send (&content, self->push, 0); } zsock_t *which = (zsock_t *) zpoller_wait (self->poller, -1); if (zpoller_terminated (self->poller)) break; else if (which == self->pipe) { s_upstream_handle_pipe (self); } } s_upstream_destroy (&self); }
void zproxy (zsock_t *pipe, void *unused) { self_t *self = s_self_new (pipe); assert (self); // Signal successful initialization zsock_signal (pipe, 0); while (!self->terminated) { zsock_t *which = (zsock_t *) zpoller_wait (self->poller, -1); if (zpoller_terminated (self->poller)) break; // Interrupted else if (which == self->pipe) s_self_handle_pipe (self); else if (which == self->frontend) s_self_switch (self, self->frontend, self->backend); else if (which == self->backend) s_self_switch (self, self->backend, self->frontend); } s_self_destroy (&self); }
void ztask_monitor_api_loop (ztask_monitor_api_t *self) { zyre_t *node = zyre_new(); zyre_set_header(node, "X-ZTASK-MON", "TASK MON"); zyre_start(node); zyre_dump(node); if (self->pub_port >= 0) zclock_log("Publisher is listening on port %d ...", self->pub_port); zpoller_t *poller = zpoller_new (zyre_socket (node), NULL); uint64_t reap_at = zclock_time () + self->pub_timeout; zyre_event_t *event; while (!zsys_interrupted) { void *which = zpoller_wait (poller, self->pub_timeout); if (zpoller_terminated (poller)) { break; } if (which == zyre_socket (node)) { event = zyre_event_new(node); if (!event) break; if (zyre_event_type(event) == ZYRE_EVENT_ENTER) { } else if (zyre_event_type(event) == ZYRE_EVENT_EXIT) { char *data = (char *) zhash_lookup(self->nodes, (const char *) zyre_event_sender(event)); if (data) { zhash_delete(self->nodes, (const char *) zyre_event_sender(event)); free(data); } } else if (zyre_event_type(event) == ZYRE_EVENT_WHISPER) { zmsg_t *msg = zyre_event_msg(event); char *cpu_str = zmsg_popstr(msg); char *mem_rss_str = zmsg_popstr(msg); if (self->pub_sock) { char *data = (char *) zhash_lookup(self->nodes, (const char *) zyre_event_sender(event)); if (data) { zhash_delete(self->nodes, (const char *) zyre_event_sender(event)); free(data); } if (asprintf(&data, "{\"id\":\"%s\",%s,%s}", zyre_event_sender(event), cpu_str, mem_rss_str) < 0) data = NULL; zhash_insert(self->nodes, (const char *) zyre_event_sender(event), data); } else { zclock_log("From %s", zyre_event_sender(event)); zclock_log(" %s", cpu_str); zclock_log(" %s", mem_rss_str); } free(cpu_str); free(mem_rss_str); } zyre_event_destroy(&event); } if (zclock_time() >= reap_at) { reap_at = zclock_time() + self->pub_timeout; if (self->pub_sock) { char *data = ztask_monitor_api_json (self); if (data) { zmsg_t *msg = zmsg_new(); zmsg_addstr(msg, data); zclock_log("Sending %s ...", data); zmsg_send(&msg, self->pub_sock); free(data); } } } } zyre_stop(node); zpoller_destroy (&poller); zyre_destroy(&node); // Cleanup of self->nodes // char *wk = (char *) zhash_first (self->nodes); // while (wk) { // zhash_delete (self->nodes, wk); //// free (data); // wk = (char *) zhash_first (self->nodes); // } }
int main (int argc, char *argv []) { puts (PRODUCT); puts (COPYRIGHT); puts (NOWARRANTY); int argn = 1; bool verbose = false; if (argn < argc && streq (argv [argn], "-h")) { puts ("syntax: hydrad [ directory ]"); puts (" -- defaults to .hydra in current directory"); exit (0); } if (argn < argc && streq (argv [argn], "-v")) { verbose = true; argn++; } // By default, current node runs in .hydra directory; create this if // it's missing (don't create directory passed as argument); char *workdir = ".hydra"; if (argn < argc) workdir = argv [argn++]; else zsys_dir_create (workdir); // ---------------------------------------------------------------------- // This code eventually goes into a reusable hydra actor class // Switch to working directory zsys_info ("hydrad: data store in %s directory", workdir); if (zsys_dir_change (workdir)) { zsys_error ("hydrad: cannot access %s: %s", workdir, strerror (errno)); return 1; } // Check we are the only process currently running here if (zsys_run_as ("hydrad.lock", NULL, NULL)) { zsys_error ("hydrad: cannot start process safely, exiting"); return 1; } // Get node identity from config file, or generate new identity zconfig_t *config = zconfig_load ("hydra.cfg"); if (!config) { // Set defaults for Hydra service config = zconfig_new ("root", NULL); zconfig_put (config, "/server/timeout", "5000"); zconfig_put (config, "/server/background", "0"); zconfig_put (config, "/server/verbose", "0"); } char *identity = zconfig_resolve (config, "/hydra/identity", NULL); if (!identity) { zuuid_t *uuid = zuuid_new (); zconfig_put (config, "/hydra/identity", zuuid_str (uuid)); zconfig_put (config, "/hydra/nickname", "Anonymous"); zconfig_save (config, "hydra.cfg"); zuuid_destroy (&uuid); } // Create store structure, if necessary zsys_dir_create ("content"); zsys_dir_create ("posts"); // Start server and bind to ephemeral TCP port. We can run many // servers on the same box, for testing. zactor_t *server = zactor_new (hydra_server, NULL); if (verbose) zstr_send (server, "VERBOSE"); // Bind Hydra service to ephemeral port and get that port number char *command; int port_nbr; zsock_send (server, "ss", "CONFIGURE", "hydra.cfg"); zsock_send (server, "ss", "BIND", "tcp://*:*"); zsock_send (server, "s", "PORT"); zsock_recv (server, "si", &command, &port_nbr); zsys_info ("hydrad: TCP server started on port=%d", port_nbr); assert (streq (command, "PORT")); free (command); // We're going to use Zyre for discovery and presence, and our own // Hydra protocol for content exchange zyre_t *zyre = zyre_new (NULL); if (verbose) zyre_set_verbose (zyre); char *hostname = zsys_hostname (); char *endpoint = zsys_sprintf ("tcp://%s:%d", hostname, port_nbr); zyre_set_header (zyre, "X-HYDRA", "%s", endpoint); zstr_free (&endpoint); zstr_free (&hostname); if (zyre_start (zyre)) { zsys_info ("hydrad: can't start Zyre discovery service"); zactor_destroy (&server); zyre_destroy (&zyre); return 1; } // When we get a new peer, handle it zpoller_t *poller = zpoller_new (zyre_socket (zyre), NULL); while (!zpoller_terminated (poller)) { void *which = zpoller_wait (poller, -1); if (which == zyre_socket (zyre)) { zyre_event_t *event = zyre_event_new (zyre); if (zyre_event_type (event) == ZYRE_EVENT_ENTER) { zsys_debug ("hydrad: new peer name=%s endpoint=%s", zyre_event_name (event), zyre_event_header (event, "X-HYDRA")); s_handle_peer (zyre_event_header (event, "X-HYDRA"), verbose); } zyre_event_destroy (&event); } else break; } zsys_info ("hydrad: shutting down..."); zpoller_destroy (&poller); // Shutdown all services zactor_destroy (&server); zyre_destroy (&zyre); zconfig_destroy (&config); return 0; }
void zyre_node_actor (zsock_t *pipe, void *args) { // Create node instance to pass around zyre_node_t *self = zyre_node_new (pipe, args); if (!self) // Interrupted return; // Signal actor successfully initialized zsock_signal (self->pipe, 0); // Loop until the agent is terminated one way or another int64_t reap_at = zclock_mono () + REAP_INTERVAL; while (!self->terminated) { // Start beacon as soon as we can if (self->beacon && self->port <= 0) { // Our hostname is provided by zbeacon zsock_send(self->beacon, "si", "CONFIGURE", self->beacon_port); char *hostname = zstr_recv(self->beacon); // Is UDP broadcast interface available? if (!streq(hostname, "")) { if (zsys_ipv6()) self->port = zsock_bind(self->inbox, "tcp://%s%%%s:*", zsys_ipv6_address(), zsys_interface()); else self->port = zsock_bind(self->inbox, "tcp://%s:*", hostname); if (self->port > 0) { assert(!self->endpoint); // If caller set this, we'd be using gossip if (streq(zsys_interface(), "*")) { char *hostname = zsys_hostname(); self->endpoint = zsys_sprintf("tcp://%s:%d", hostname, self->port); zstr_free(&hostname); } else { self->endpoint = strdup(zsock_endpoint(self->inbox)); } // Set broadcast/listen beacon beacon_t beacon; beacon.protocol[0] = 'Z'; beacon.protocol[1] = 'R'; beacon.protocol[2] = 'E'; beacon.version = BEACON_VERSION; beacon.port = htons(self->port); zuuid_export(self->uuid, beacon.uuid); zsock_send(self->beacon, "sbi", "PUBLISH", (byte *)&beacon, sizeof(beacon_t), self->interval); zsock_send(self->beacon, "sb", "SUBSCRIBE", (byte *) "ZRE", 3); zpoller_add(self->poller, self->beacon); // Start polling on inbox zpoller_add(self->poller, self->inbox); } } zstr_free(&hostname); } int timeout = (int) (reap_at - zclock_mono ()); if (timeout > REAP_INTERVAL) timeout = REAP_INTERVAL; else if (timeout < 0) timeout = 0; zsock_t *which = (zsock_t *) zpoller_wait (self->poller, timeout); if (which == self->pipe) zyre_node_recv_api (self); else if (which == self->inbox) zyre_node_recv_peer (self); else if (self->beacon && (void *) which == self->beacon) zyre_node_recv_beacon (self); else if (self->gossip && (zactor_t *) which == self->gossip) zyre_node_recv_gossip (self); else if (zpoller_terminated (self->poller)) break; // Interrupted, check before expired else if (zpoller_expired (self->poller)) { if (zclock_mono () >= reap_at) { void *item; reap_at = zclock_mono () + REAP_INTERVAL; // Ping all peers and reap any expired ones for (item = zhash_first (self->peers); item != NULL; item = zhash_next (self->peers)) zyre_node_ping_peer (zhash_cursor (self->peers), item, self); } } } zyre_node_destroy (&self); }
bool poller::terminated() { return zpoller_terminated(self_); }
static rsRetVal rcvData(){ DEFiRet; if(!listenerList) { listenerList = zlist_new(); if(!listenerList) { errmsg.LogError(0, NO_ERRCODE, "could not allocate list"); ABORT_FINALIZE(RS_RET_ERR); } } zactor_t *authActor; zcert_t *serverCert; if(runModConf->authenticator == 1) { authActor = zactor_new(zauth, NULL); zstr_sendx(authActor, "CURVE", runModConf->clientCertPath, NULL); zsock_wait(authActor); } instanceConf_t *inst; for(inst = runModConf->root; inst != NULL; inst=inst->next) { CHKiRet(addListener(inst)); } zpoller_t *poller = zpoller_new(NULL); if(!poller) { errmsg.LogError(0, NO_ERRCODE, "could not create poller"); ABORT_FINALIZE(RS_RET_ERR); } DBGPRINTF("imczmq: created poller\n"); struct listener_t *pData; pData = zlist_first(listenerList); if(!pData) { errmsg.LogError(0, NO_ERRCODE, "imczmq: no listeners were " "started, input not activated.\n"); ABORT_FINALIZE(RS_RET_NO_RUN); } while(pData) { int rc = zpoller_add(poller, pData->sock); if(rc != 0) { errmsg.LogError(0, NO_ERRCODE, "imczmq: could not add " "socket to poller, input not activated.\n"); ABORT_FINALIZE(RS_RET_NO_RUN); } pData = zlist_next(listenerList); } zframe_t *frame; zsock_t *which = (zsock_t *)zpoller_wait(poller, -1); while(which) { if (zpoller_terminated(poller)) { break; } pData = zlist_first(listenerList); while(pData->sock != which) { pData = zlist_next(listenerList); } if(which == pData->sock) { DBGPRINTF("imczmq: found matching socket\n"); } frame = zframe_recv(which); char *buf = zframe_strdup(frame); if(buf == NULL) { DBGPRINTF("imczmq: null buffer\n"); continue; } smsg_t *pMsg; if(msgConstruct(&pMsg) == RS_RET_OK) { MsgSetRawMsg(pMsg, buf, strlen(buf)); MsgSetInputName(pMsg, s_namep); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); MsgSetRcvFromIP(pMsg, glbl.GetLocalHostIP()); MsgSetMSGoffs(pMsg, 0); MsgSetFlowControlType(pMsg, eFLOWCTL_NO_DELAY); MsgSetRuleset(pMsg, pData->ruleset); pMsg->msgFlags = NEEDS_PARSING | PARSE_HOSTNAME; submitMsg2(pMsg); } free(buf); which = (zsock_t *)zpoller_wait(poller, -1); } finalize_it: zframe_destroy(&frame); zpoller_destroy(&poller); pData = zlist_first(listenerList); while(pData) { zsock_destroy(&pData->sock); free(pData->ruleset); pData = zlist_next(listenerList); } zlist_destroy(&listenerList); zactor_destroy(&authActor); zcert_destroy(&serverCert); RETiRet; }
/// // Return true if the last zpoller_wait () call ended because the process // was interrupted, or the parent context was destroyed. bool QZpoller::terminated () { bool rv = zpoller_terminated (self); return rv; }
JNIEXPORT jboolean JNICALL Java_org_zeromq_czmq_Zpoller__1_1terminated (JNIEnv *env, jclass c, jlong self) { jboolean terminated_ = (jboolean) zpoller_terminated ((zpoller_t *) (intptr_t) self); return terminated_; }
void broker_run (broker_t *self) { // Only accepting requests when executors available. bool accepting_requests = false; while (1) { zsock_t *which = (zsock_t *) zpoller_wait (self->poller, 10); if (which == self->contexts) { puts ("[BROKER] which == self->contexts"); // [context] [request] zmsg_t *msg = zmsg_recv (self->contexts); assert (msg); if (0 != broker_send_to_executor (self, msg)) zlist_append (self->backlog, msg); // Remove contexts from poller if no executors if (zlist_size (self->executor_lb) == 0) { zpoller_remove (self->poller, self->contexts); accepting_requests = false; } } else if (which == self->executors) { puts ("[BROKER] which == self->executors"); // EITHER: // [executor] ["READY"] // [executor] [context] [response] zmsg_t *msg = zmsg_recv (self->executors); assert (msg); zframe_t *executor_addr = zmsg_pop (msg); assert (executor_addr); zframe_t *ctx_or_ready = zmsg_pop (msg); char *context_addr = zframe_strdup (ctx_or_ready); if (strcmp (context_addr, "READY") != 0) { // Forward the response to the correct context addr. // [context] [0] [response] zmsg_prepend (msg, &ctx_or_ready); zmsg_send (&msg, self->contexts); } else { // Got a READY message // Put the executor ID back in the available queue zlist_append (self->executor_lb, executor_addr); // We know at least one executor is now available, // so check and assign backlog tasks. broker_check_backlog (self); // If we now have executors but not accepting requests, // then start polling on the frontend socket. if (!accepting_requests && zlist_size (self->executor_lb)) { zpoller_add (self->poller, self->contexts); accepting_requests = true; } // Destroy the READY message. zmsg_destroy (&msg); } } else if (zpoller_terminated (self->poller)) break; } }
/// // Return true if the last zpoller_wait () call ended because the process // was interrupted, or the parent context was destroyed. bool QmlZpoller::terminated () { return zpoller_terminated (self); };
void zpoller_test (bool verbose) { printf (" * zpoller: "); // @selftest // Create a few sockets zsock_t *vent = zsock_new (ZMQ_PUSH); assert (vent); int port_nbr = zsock_bind (vent, "tcp://127.0.0.1:*"); assert (port_nbr != -1); zsock_t *sink = zsock_new (ZMQ_PULL); assert (sink); int rc = zsock_connect (sink, "tcp://127.0.0.1:%d", port_nbr); assert (rc != -1); zsock_t *bowl = zsock_new (ZMQ_PULL); assert (bowl); zsock_t *dish = zsock_new (ZMQ_PULL); assert (dish); // Set up poller zpoller_t *poller = zpoller_new (bowl, dish, NULL); assert (poller); // Add a reader to the existing poller rc = zpoller_add (poller, sink); assert (rc == 0); zstr_send (vent, "Hello, World"); // We expect a message only on the sink zsock_t *which = (zsock_t *) zpoller_wait (poller, -1); assert (which == sink); assert (zpoller_expired (poller) == false); assert (zpoller_terminated (poller) == false); char *message = zstr_recv (which); assert (streq (message, "Hello, World")); zstr_free (&message); // Stop polling reader rc = zpoller_remove (poller, sink); assert (rc == 0); // Removing a non-existent reader shall fail rc = zpoller_remove (poller, sink); assert (rc == -1); assert (errno == EINVAL); // Check we can poll an FD rc = zsock_connect (bowl, "tcp://127.0.0.1:%d", port_nbr); assert (rc != -1); SOCKET fd = zsock_fd (bowl); rc = zpoller_add (poller, (void *) &fd); assert (rc != -1); zstr_send (vent, "Hello again, world"); assert (zpoller_wait (poller, 500) == &fd); // Check zpoller_set_nonstop () zsys_interrupted = 1; zpoller_wait (poller, 0); assert (zpoller_terminated (poller)); zpoller_set_nonstop (poller, true); zpoller_wait (poller, 0); assert (!zpoller_terminated (poller)); zsys_interrupted = 0; zpoller_destroy (&poller); zsock_destroy (&vent); zsock_destroy (&sink); zsock_destroy (&bowl); zsock_destroy (&dish); #ifdef ZMQ_SERVER // Check thread safe sockets zpoller_destroy (&poller); zsock_t *client = zsock_new (ZMQ_CLIENT); assert (client); zsock_t *server = zsock_new (ZMQ_SERVER); assert (server); poller = zpoller_new (client, server, NULL); assert (poller); port_nbr = zsock_bind (server, "tcp://127.0.0.1:*"); assert (port_nbr != -1); rc = zsock_connect (client, "tcp://127.0.0.1:%d", port_nbr); assert (rc != -1); zstr_send (client, "Hello, World"); // We expect a message only on the server which = (zsock_t *) zpoller_wait (poller, -1); assert (which == server); assert (zpoller_expired (poller) == false); assert (zpoller_terminated (poller) == false); message = zstr_recv (which); assert (streq (message, "Hello, World")); zstr_free (&message); zpoller_destroy (&poller); zsock_destroy (&client); zsock_destroy (&server); #endif #if defined (__WINDOWS__) zsys_shutdown(); #endif // @end printf ("OK\n"); }
void zsync_node_engine (void *args, zctx_t *ctx, void *pipe) { int rc; zsync_node_t *self = zsync_node_new (); self->ctx = ctx; self->zyre = zyre_new (ctx); self->zsync_pipe = pipe; // Join group rc = zyre_join (self->zyre, "ZSYNC"); assert (rc == 0); // Give time to interconnect zclock_sleep (250); zpoller_t *poller = zpoller_new (zyre_socket (self->zyre), self->zsync_pipe, NULL); // Create thread for file management self->file_pipe = zthread_fork (self->ctx, zsync_ftmanager_engine, NULL); zpoller_add (poller, self->file_pipe); // Create thread for credit management self->credit_pipe = zthread_fork (self->ctx, zsync_credit_manager_engine, NULL); zpoller_add (poller, self->credit_pipe); // Start receiving messages printf("[ND] started\n"); while (!zpoller_terminated (poller)) { void *which = zpoller_wait (poller, -1); if (which == zyre_socket (self->zyre)) { zsync_node_recv_from_zyre (self); } else if (which == self->zsync_pipe) { printf("[ND] Recv Agent\n"); zsync_node_recv_from_agent (self); } else if (which == self->file_pipe) { printf("[ND] Recv FT Manager\n"); zsync_ftm_msg_t *msg = zsync_ftm_msg_recv (self->file_pipe); char *receiver = zsync_ftm_msg_receiver (msg); char *zyre_uuid = zsync_node_zyre_uuid (self, receiver); if (zyre_uuid) { char *path = zsync_ftm_msg_path (msg); uint64_t sequence = zsync_ftm_msg_sequence (msg); uint64_t chunk_size = zsync_ftm_msg_chunk_size (msg); uint64_t offset = zsync_ftm_msg_offset (msg); zsync_msg_send_req_chunk (pipe, path, chunk_size, offset); zsync_msg_t *zsmsg = zsync_msg_recv (pipe); zchunk_t *chunk = zsync_msg_chunk (zsmsg); zframe_t *frame = zframe_new (zchunk_data (chunk), zchunk_size (chunk)); zmsg_t *zmsg = zmsg_new (); zs_msg_pack_chunk (zmsg, sequence, path, offset, frame); zyre_whisper (self->zyre, zyre_uuid, &zmsg); zsync_ftm_msg_destroy (&msg); zsync_msg_destroy (&zsmsg); } } else if (which == self->credit_pipe) { printf("[ND] Recv Credit Manager\n"); zsync_credit_msg_t *cmsg = zsync_credit_msg_recv (self->credit_pipe); char *receiver = zsync_credit_msg_receiver (cmsg); char *zyre_uuid = zsync_node_zyre_uuid (self, receiver); if (zyre_uuid) { zmsg_t *credit_msg = zsync_credit_msg_credit (cmsg); assert (rc == 0); zyre_whisper (self->zyre, zyre_uuid, &credit_msg); } zsync_credit_msg_destroy (&cmsg); } if (self->terminated) { break; } } zpoller_destroy (&poller); zsync_node_destroy (&self); printf("[ND] stopped\n"); }