static subscriber_state_t* subscriber_state_new(zsock_t *pipe, zconfig_t* config, zlist_t *devices) { // figure out devices specs if (devices == NULL) devices = zlist_new(); if (zlist_size(devices) == 0) { zlist_destroy(&devices); devices = extract_devices_from_config(config); } if (zlist_size(devices) == 0) zlist_append(devices, augment_zmq_connection_spec("localhost", sub_port)); //create the state subscriber_state_t *state = zmalloc(sizeof(*state)); state->pipe = pipe; state->devices = devices; state->sub_socket = subscriber_sub_socket_new(config, state->devices); state->tracker = device_tracker_new(devices, state->sub_socket); state->pull_socket = subscriber_pull_socket_new(config); state->router_socket = subscriber_router_socket_new(config); state->push_socket = subscriber_push_socket_new(config); if (PUBLISH_DUPLICATES) state->pub_socket = subscriber_pub_socket_new(config); return state; }
void zdir_remove (zdir_t *self, bool force) { // If forced, remove all subdirectories and files if (force) { zfile_t *file = (zfile_t *) zlist_pop (self->files); while (file) { zfile_remove (file); zfile_destroy (&file); file = (zfile_t *) zlist_pop (self->files); } zdir_t *subdir = (zdir_t *) zlist_pop (self->subdirs); while (subdir) { zdir_remove (subdir, force); zdir_destroy (&subdir); subdir = (zdir_t *) zlist_pop (self->subdirs); } self->cursize = 0; self->count = 0; } // Remove if empty if (zlist_size (self->files) == 0 && zlist_size (self->subdirs) == 0) zsys_dir_delete (self->path); }
int zmsg_send (zmsg_t **self_p, void *dest) { assert (self_p); assert (dest); zmsg_t *self = *self_p; int rc = 0; void *handle = zsock_resolve (dest); if (self) { assert (zmsg_is (self)); if (zlist_size (self->frames) == 0) return -1; // Sending an empty message is an error zframe_t *frame = (zframe_t *) zlist_pop (self->frames); while (frame) { rc = zframe_send (&frame, handle, zlist_size (self->frames)? ZFRAME_MORE: 0); if (rc != 0) break; frame = (zframe_t *) zlist_pop (self->frames); } zmsg_destroy (self_p); } return rc; }
int zpoller_remove (zpoller_t *self, void *reader) { assert (self); assert (reader); int rc = 0; #ifdef ZMQ_HAVE_POLLER void *socket = zsock_resolve (reader); if (socket) rc = zmq_poller_remove (self->zmq_poller, socket); else rc = zmq_poller_remove_fd (self->zmq_poller, *(SOCKET *) reader); #else size_t num_readers_before = zlist_size (self->reader_list); zlist_remove (self->reader_list, reader); // won't fail with non-existent reader size_t num_readers_after = zlist_size (self->reader_list); if (num_readers_before != num_readers_after) self->need_rebuild = true; else { errno = EINVAL; rc = -1; } #endif return rc; }
static void s_engine_destroy (engine_t **self_p) { assert (self_p); if (*self_p) { engine_t *self = *self_p; mdp_worker_destroy (&self->worker); // Destroy remaining sell orders while (zlist_size (self->sell_orders) > 0) { order_t *order = (order_t *) zlist_pop (self->sell_orders); s_order_destroy(&order); } zlist_destroy (&self->sell_orders); // Destroy remaining buy orders while (zlist_size (self->buy_orders) > 0) { order_t *order = (order_t *) zlist_pop (self->buy_orders); s_order_destroy(&order); } zlist_destroy (&self->buy_orders); free (self); *self_p = NULL; } }
void zloop_destroy (zloop_t **self_p) { assert (self_p); if (*self_p) { zloop_t *self = *self_p; // Destroy list of readers while (zlist_size (self->readers)) free (zlist_pop (self->readers)); zlist_destroy (&self->readers); // Destroy list of pollers while (zlist_size (self->pollers)) free (zlist_pop (self->pollers)); zlist_destroy (&self->pollers); // Destroy list of timers while (zlist_size (self->timers)) free (zlist_pop (self->timers)); zlist_destroy (&self->timers); // Destroy zombie timer list // Which must always be empty here assert (zlist_size (self->zombies) == 0); zlist_destroy (&self->zombies); free (self->pollset); free (self->readact); free (self->pollact); free (self); *self_p = NULL; } }
int main (void) { zctx_t *ctx = zctx_new (); void *frontend = zsocket_new (ctx, ZMQ_ROUTER); void *backend = zsocket_new (ctx, ZMQ_ROUTER); zsocket_bind (frontend, "tcp://*:5555"); // For clients zsocket_bind (backend, "tcp://*:5556"); // For workers // Queue of available workers zlist_t *workers = zlist_new (); // The body of this example is exactly the same as lruqueue2. // .skip while (1) { zmq_pollitem_t items [] = { { backend, 0, ZMQ_POLLIN, 0 }, { frontend, 0, ZMQ_POLLIN, 0 } }; // Poll frontend only if we have available workers int rc = zmq_poll (items, zlist_size (workers)? 2: 1, -1); if (rc == -1) break; // Interrupted // Handle worker activity on backend if (items [0].revents & ZMQ_POLLIN) { // Use worker address for LRU routing zmsg_t *msg = zmsg_recv (backend); if (!msg) break; // Interrupted zframe_t *address = zmsg_unwrap (msg); zlist_append (workers, address); // Forward message to client if it's not a READY zframe_t *frame = zmsg_first (msg); if (memcmp (zframe_data (frame), LRU_READY, 1) == 0) zmsg_destroy (&msg); else zmsg_send (&msg, frontend); } if (items [1].revents & ZMQ_POLLIN) { // Get client request, route to first available worker zmsg_t *msg = zmsg_recv (frontend); if (msg) { zmsg_wrap (msg, (zframe_t *) zlist_pop (workers)); zmsg_send (&msg, backend); } } } // When we're done, clean up properly while (zlist_size (workers)) { zframe_t *frame = (zframe_t *) zlist_pop (workers); zframe_destroy (&frame); } zlist_destroy (&workers); zctx_destroy (&ctx); return 0; // .until }
// Distribute all backlog messages while are workers available. // Failed-to-send messages are put back in the backlog. void broker_check_backlog (broker_t *self) { while (zlist_size (self->backlog) && zlist_size (self->executor_lb)) { zmsg_t *backlog_msg = zlist_pop (self->backlog); if (0 != broker_send_to_executor (self, backlog_msg)) zlist_append (self->backlog, backlog_msg); } }
static int s_on_read_timer (zloop_t *loop, int timer_id, void *arg) { zdir_watch_t *watch = (zdir_watch_t *) arg; void *data; for (data = zhash_first (watch->subs); data != NULL; data = zhash_next (watch->subs)) { zdir_watch_sub_t *sub = (zdir_watch_sub_t *) data; zdir_t *new_dir = zdir_new (zdir_path (sub->dir), NULL); if (!new_dir) { if (watch->verbose) zsys_error ("zdir_watch: Unable to create new zdir for path %s", zdir_path (sub->dir)); continue; } // Determine if anything has changed. zlist_t *diff = zdir_diff (sub->dir, new_dir, ""); // Do memory management before error handling... zdir_destroy (&sub->dir); sub->dir = new_dir; if (!diff) { if (watch->verbose) zsys_error ("zdir_watch: Unable to create diff for path %s", zdir_path (sub->dir)); continue; } if (zlist_size (diff) > 0) { if (watch->verbose) { zdir_patch_t *patch = (zdir_patch_t *) zlist_first (diff); zsys_info ("zdir_watch: Found %d changes in %s:", zlist_size (diff), zdir_path (sub->dir)); while (patch) { zsys_info ("zdir_watch: %s %s", zfile_filename (zdir_patch_file (patch), NULL), zdir_patch_op (patch) == ZDIR_PATCH_CREATE? "created": "deleted"); patch = (zdir_patch_t *) zlist_next (diff); } } if (zsock_send (watch->pipe, "sp", zdir_path (sub->dir), diff) != 0) { if (watch->verbose) zsys_error ("zdir_watch: Unable to send patch list for path %s", zdir_path (sub->dir)); zlist_destroy (&diff); } // Successfully sent `diff` list - now owned by receiver } else { zlist_destroy (&diff); } } return 0; }
static zsock_t* subscriber_sub_socket_new(subscriber_state_t *state) { zsock_t *socket = zsock_new(ZMQ_SUB); assert(socket); zsock_set_rcvhwm(socket, state->rcv_hwm); // set subscription if (!state->subscriptions || zlist_size(state->subscriptions) == 0) { if (!state->subscriptions) state->subscriptions = zlist_new(); zlist_append(state->subscriptions, zconfig_resolve(state->config, "/logjam/subscription", "")); } char *subscription = zlist_first(state->subscriptions); bool subscribed_to_all = false; while (subscription) { printf("[I] subscriber: subscribing to '%s'\n", subscription); if (streq(subscription, "")) subscribed_to_all = true; zsock_set_subscribe(socket, subscription); subscription = zlist_next(state->subscriptions); } if (!subscribed_to_all) zsock_set_subscribe(socket, "heartbeat"); if (!state->devices || zlist_size(state->devices) == 0) { // convert config file to list of devices if (!state->devices) state->devices = zlist_new(); zconfig_t *endpoints = zconfig_locate(state->config, "/logjam/endpoints"); if (!endpoints) { zlist_append(state->devices, "tcp://localhost:9606"); } else { zconfig_t *endpoint = zconfig_child(endpoints); while (endpoint) { char *spec = zconfig_value(endpoint); char *new_spec = augment_zmq_connection_spec(spec, 9606); zlist_append(state->devices, new_spec); endpoint = zconfig_next(endpoint); } } } char* device = zlist_first(state->devices); while (device) { printf("[I] subscriber: connecting SUB socket to logjam-device via %s\n", device); int rc = zsock_connect(socket, "%s", device); log_zmq_error(rc, __FILE__, __LINE__); assert(rc == 0); device = zlist_next(state->devices); } return socket; }
bool kdt_point_equal_float (kdt_point_t *A, kdt_point_t *B) { int n_components_A = zlist_size (A->list); int n_components_B = zlist_size (B->list); assert (n_components_A == n_components_B); bool still_equal = true; for (int counter = 0; counter < n_components_A; counter++) { still_equal = ( kdt_point_index_float (A, counter) == kdt_point_index_float (B, counter) ); if (!still_equal) break; } return still_equal; }
END_TEST // -------------------------------------------------------------------------- /// Try to _get () a zlist_t * without any values START_TEST(test_msg_get_l_empty) { sam_selftest_introduce ("test_msg_get_l_empty"); zmsg_t *zmsg = zmsg_new (); if (zmsg_pushstr (zmsg, "0")) { ck_abort_msg ("could not build zmsg"); } sam_msg_t *msg = sam_msg_new (&zmsg); ck_assert_int_eq (sam_msg_size (msg), 1); zlist_t *list; int rc = sam_msg_get (msg, "l", &list); ck_assert_int_eq (rc, 0); ck_assert_int_eq (sam_msg_size (msg), 1); ck_assert_int_eq (zlist_size (list), 0); zlist_destroy (&list); sam_msg_destroy (&msg); }
static void peering_raise (peering_t *self) { vocket_t *vocket = self->vocket; driver_t *driver = self->driver; if (driver->verbose) zclock_log ("I: (tcp) bring up peering to %s", self->address); if (!self->alive) { self->alive = TRUE; zlist_append (vocket->live_peerings, self); // Send ZMTP handshake, which is an empty message zmq_msg_t msg; zmq_msg_init_size (&msg, 0); s_queue_output (self, &msg, FALSE); // If we can now route to peerings, start reading from msgpipe if (zlist_size (vocket->live_peerings) == vocket->min_peerings) { // Ask reactor to start monitoring vocket's msgpipe pipe zmq_pollitem_t item = { vocket->msgpipe, 0, ZMQ_POLLIN, 0 }; zloop_poller (driver->loop, &item, s_vocket_input, vocket); } } }
void multi_job_check (struct queue *queue) { zlist_t *newjobs; json_t *jobs; ok (queue_size (queue) == 0, "queue is initially empty"); if (!(jobs = json_pack ("[{s:I s:i s:i s:f s:i}," "{s:I s:i s:i s:f s:i}]", "id", 1, "priority", 10, "userid", 42, "t_submit", 1.0, "flags", 0, "id", 2, "priority", 11, "userid", 43, "t_submit", 1.1, "flags", 1))) BAIL_OUT ("json_pack() failed"); newjobs = submit_enqueue_jobs (queue, jobs); ok (newjobs != NULL, "submit_enqueue_jobs works"); ok (queue_size (queue) == 2, "queue contains 2 jobs"); ok (zlist_size (newjobs) == 2, "newjobs contains 2 jobs"); submit_enqueue_jobs_cleanup (queue, newjobs); ok (queue_size (queue) == 0, "submit_enqueue_jobs_cleanup removed queue entries"); json_decref (jobs); }
void rrwrk_print(rrwrk_t *self) { printf("\n=========================================================================\n"); printf("W: live %Zd, hb %d\n", self->liveness, self->heartbeat); printf("W: waiting list %Zd\n", zlist_size(self->data)); printf("W: received %Zd, finished %Zd\n", self->total_received, self->total_finished); }
int zmsg_send (zmsg_t **self_p, void *dest) { assert (self_p); assert (dest); zmsg_t *self = *self_p; int rc = 0; if (self) { assert (zmsg_is (self)); bool sent_some = false; zframe_t *frame; while ((frame = (zframe_t *) zlist_head (self->frames))) { rc = zframe_send (&frame, dest, zlist_size (self->frames) > 1 ? ZFRAME_MORE : 0); if (rc != 0) { if (errno == EINTR && sent_some) continue; else break; } sent_some = true; (void) zlist_pop (self->frames); } if (rc == 0) zmsg_destroy (self_p); } return rc; }
// Handle input from worker, on backend int s_handle_backend(zloop_t *loop, zmq_pollitem_t *poller, void *arg) { // Use worker identity for load-balancing lbbroker_t *self = (lbbroker_t *)arg; zmsg_t *msg = zmsg_recv(self->backend); if (msg) { zframe_t *identity = zmsg_unwrap(msg); zlist_append(self->workers, identity); // Enable reader on frontend if we went from 0 to 1 workers if (zlist_size(self->workers) == 1) { zmq_pollitem_t poller = { self->frontend, 0, ZMQ_POLLIN }; zloop_poller(loop, &poller, s_handle_frontend, self); } // Forward message to client if it's not a READY zframe_t *frame = zmsg_first(msg); if (memcmp(zframe_data(frame), WORKER_READY, strlen(WORKER_READY)) == 0) { zmsg_destroy(&msg); } else { zmsg_send(&msg, self->frontend); } } return 0; }
void zcert_test (bool verbose) { printf (" * zcert: "); #if (ZMQ_VERSION_MAJOR == 4) // @selftest // Create temporary directory for test files # define TESTDIR ".test_zcert" zsys_dir_create (TESTDIR); // Create a simple certificate with metadata zcert_t *cert = zcert_new (); # if defined (HAVE_LIBSODIUM) zcert_set_meta (cert, "email", "*****@*****.**"); zcert_set_meta (cert, "name", "Pieter Hintjens"); zcert_set_meta (cert, "organization", "iMatix Corporation"); zcert_set_meta (cert, "version", "%d", 1); assert (streq (zcert_meta (cert, "email"), "*****@*****.**")); zlist_t *keys = zcert_meta_keys (cert); assert (zlist_size (keys) == 4); zlist_destroy (&keys); // Check the dup and eq methods zcert_t *shadow = zcert_dup (cert); assert (zcert_eq (cert, shadow)); zcert_destroy (&shadow); // Check we can save and load certificate zcert_save (cert, TESTDIR "/mycert.txt"); assert (zsys_file_exists (TESTDIR "/mycert.txt")); assert (zsys_file_exists (TESTDIR "/mycert.txt_secret")); // Load certificate, will in fact load secret one shadow = zcert_load (TESTDIR "/mycert.txt"); assert (shadow); assert (zcert_eq (cert, shadow)); zcert_destroy (&shadow); // Delete secret certificate, load public one int rc = zsys_file_delete (TESTDIR "/mycert.txt_secret"); assert (rc == 0); shadow = zcert_load (TESTDIR "/mycert.txt"); // 32-byte null key encodes as 40 '0' characters assert (streq (zcert_secret_txt (shadow), "0000000000000000000000000000000000000000")); zcert_destroy (&shadow); zcert_destroy (&cert); # else // Libsodium isn't installed; should have returned NULL assert (cert == NULL); # endif // Delete all test files zdir_t *dir = zdir_new (TESTDIR, NULL); zdir_remove (dir, true); zdir_destroy (&dir); // @end #endif printf ("OK\n"); }
static void s_check_directory (s_agent_t *self) { // Get latest snapshot and build a patches list for any changes // All patches are built using a virtual path starting at "/" zdir_t *dir = zdir_new (self->path, NULL); zlist_t *patches = zdir_diff (self->dir, dir, "/"); // Drop old directory and replace with latest version zdir_destroy (&self->dir); self->dir = dir; while (zlist_size (patches)) { zdir_patch_t *patch = (zdir_patch_t *) zlist_pop (patches); if (zdir_patch_op (patch) == patch_create) { // Shout new files to DROPS group // Stupidest possible approach: send whole file as one frame // Truncate file at arbitrary limit of 10MB zfile_t *file = zdir_patch_file (patch); if (zfile_input (file) == 0) { zchunk_t *chunk = zfile_read (file, 10 * 1024 * 1024, 0); assert (chunk); zmsg_t *msg = zmsg_new (); zmsg_addstr (msg, "CREATE"); zmsg_addstr (msg, zdir_patch_vpath (patch)); zmsg_add (msg, zframe_new (zchunk_data (chunk), zchunk_size (chunk))); zchunk_destroy (&chunk); zyre_shout (self->zyre, "DROPS", &msg); } } zdir_patch_destroy (&patch); } zlist_destroy (&patches); }
static bool mount_refresh (mount_t *self, server_t *server) { bool activity = false; // Get latest snapshot and build a patches list for any changes fmq_dir_t *latest = fmq_dir_new (self->location, NULL); zlist_t *patches = fmq_dir_diff (self->dir, latest, self->alias); // Drop old directory and replace with latest version fmq_dir_destroy (&self->dir); self->dir = latest; // Copy new patches to clients' patches list sub_t *sub = (sub_t *) zlist_first (self->subs); while (sub) { fmq_patch_t *patch = (fmq_patch_t *) zlist_first (patches); while (patch) { sub_patch_add (sub, patch); patch = (fmq_patch_t *) zlist_next (patches); activity = true; } sub = (sub_t *) zlist_next (self->subs); } // Destroy patches, they've all been copied while (zlist_size (patches)) { fmq_patch_t *patch = (fmq_patch_t *) zlist_pop (patches); fmq_patch_destroy (&patch); } zlist_destroy (&patches); return activity; }
static int s_rebuild_pollset (zloop_t *self) { free (self->pollset); free (self->pollact); self->pollset = NULL; self->pollact = NULL; self->poll_size = zlist_size (self->pollers); self->pollset = (zmq_pollitem_t *) zmalloc ( self->poll_size * sizeof (zmq_pollitem_t)); if (!self->pollset) return -1; self->pollact = (s_poller_t *) zmalloc ( self->poll_size * sizeof (s_poller_t)); if (!self->pollact) return -1; s_poller_t *poller = (s_poller_t *) zlist_first (self->pollers); uint item_nbr = 0; while (poller) { self->pollset [item_nbr] = poller->item; self->pollact [item_nbr] = *poller; item_nbr++; poller = (s_poller_t *) zlist_next (self->pollers); } self->need_rebuild = false; return 0; }
static void s_service_dispatch(service_t *self, zmsg_t *msg) { assert(self); if (msg) { // Queue message if any zlist_append(self->requests, msg); } s_broker_purge(self->broker); while (zlist_size(self->waiting) && zlist_size(self->requests)) { worker_t *worker = zlist_pop(self->waiting); zlist_remove(self->broker->waiting, worker); zmsg_t *msg = zlist_pop(self->requests); s_worker_send(worker, MDPW_REQUEST, msg); zmsg_destroy (&msg); } }
zlist_t * get_update (uint64_t from_state) { printf("[ST] GET_UPDATE\n"); zlist_t *filemeta_list = zlist_new (); DIR *dir; struct dirent *ent; if ((dir = opendir ("./syncfolder")) != NULL) { /* print all the files and directories within directory */ while ((ent = readdir (dir)) != NULL) { if (strcmp (ent->d_name, ".") != 0 && strcmp (ent->d_name, "..") != 0) { struct stat st; stat(ent->d_name, &st); zs_fmetadata_t *fmetadata = zs_fmetadata_new (); zs_fmetadata_set_path (fmetadata, "%s", ent->d_name); zs_fmetadata_set_size (fmetadata, st.st_size); zs_fmetadata_set_operation (fmetadata, ZS_FILE_OP_UPD); zs_fmetadata_set_timestamp (fmetadata, st.st_ctime); zs_fmetadata_set_checksum (fmetadata, 0x3312AFFDE12); zlist_append(filemeta_list, fmetadata); } } closedir (dir); } if (zlist_size (filemeta_list) > 0) { return filemeta_list; } else { return NULL; } }
/* timer adds zmsgs to zlist, then stops reactor after 100. */ void test_ev_zlist (void) { struct ev_loop *loop; ev_zlist list_w; ev_timer timer_w; zlist_t *l; zmsg_t *zmsg; ok ((loop = ev_loop_new (EVFLAG_AUTO)) != NULL, "ev_loop_new works"); if (!(l = zlist_new ()) || !(zmsg = zmsg_new ()) || zlist_append (l, zmsg) < 0) oom (); ev_zlist_init (&list_w, list_cb, l, EV_READ); ev_timer_init (&timer_w, list_timer_cb, 1E-3, 1E-3); timer_w.data = l; ev_zlist_start (loop, &list_w); ev_timer_start (loop, &timer_w); ok (ev_run (loop, 0) != 0 && zlist_size (l) == 0, "ev_zlist handler ran 100 times"); ev_zlist_stop (loop, &list_w); ev_timer_stop (loop, &timer_w); if (l) zlist_destroy (&l); ev_loop_destroy (loop); }
static int s_rebuild_poll_set (zpoller_t *self) { freen (self->poll_set); self->poll_set = NULL; freen (self->poll_readers); self->poll_readers = NULL; self->poll_size = zlist_size (self->reader_list); self->poll_set = (zmq_pollitem_t *) zmalloc (self->poll_size * sizeof (zmq_pollitem_t)); self->poll_readers = (void **) zmalloc (self->poll_size * sizeof (void *)); if (!self->poll_set || !self->poll_readers) return -1; uint reader_nbr = 0; void *reader = zlist_first (self->reader_list); while (reader) { self->poll_readers [reader_nbr] = reader; void *socket = zsock_resolve (reader); if (socket == NULL) { self->poll_set [reader_nbr].socket = NULL; self->poll_set [reader_nbr].fd = *(SOCKET *) reader; } else self->poll_set [reader_nbr].socket = socket; self->poll_set [reader_nbr].events = ZMQ_POLLIN; reader_nbr++; reader = zlist_next (self->reader_list); } self->need_rebuild = false; return 0; }
END_TEST // -------------------------------------------------------------------------- /// Try to _get () a zlist_t START_TEST(test_msg_get_l) { sam_selftest_introduce ("test_msg_get_l"); zmsg_t *zmsg = zmsg_new (); if (zmsg_pushstr (zmsg, "value2") || zmsg_pushstr (zmsg, "value1") || zmsg_pushstr (zmsg, "2")) { ck_abort_msg ("could not build zmsg"); } sam_msg_t *msg = sam_msg_new (&zmsg); ck_assert_int_eq (sam_msg_size (msg), 3); zlist_t *list; int rc = sam_msg_get (msg, "l", &list); ck_assert_int_eq (rc, 0); ck_assert_int_eq (sam_msg_size (msg), 3); ck_assert_int_eq (zlist_size (list), 2); ck_assert_str_eq (zlist_first (list), "value1"); ck_assert_str_eq (zlist_next (list), "value2"); ck_assert (zlist_next (list) == NULL); // check idempotency of _get () zlist_destroy (&list); rc = sam_msg_get (msg, "l", &list); ck_assert_int_eq (rc, 0); ck_assert_int_eq (sam_msg_size (msg), 3); ck_assert_int_eq (zlist_size (list), 2); ck_assert_str_eq (zlist_first (list), "value1"); ck_assert_str_eq (zlist_next (list), "value2"); ck_assert (zlist_next (list) == NULL); zlist_destroy (&list); sam_msg_destroy (&msg); }
static void * flcliapi_task (void *context) { agent_t *self = agent_new (context, "inproc://flcliapi"); zmq_pollitem_t items [] = { { self->control, 0, ZMQ_POLLIN, 0 }, { self->router, 0, ZMQ_POLLIN, 0 } }; while (!s_interrupted) { // Calculate tickless timer, up to 1 hour uint64_t tickless = s_clock () + 1000 * 3600; if (self->request && tickless > self->expires) tickless = self->expires; zhash_apply (self->servers, server_tickless, &tickless); int rc = zmq_poll (items, 2, (tickless - s_clock ()) * 1000); if (rc == -1 && errno == ETERM) break; // Context has been shut down if (items [0].revents & ZMQ_POLLIN) agent_control_message (self); if (items [1].revents & ZMQ_POLLIN) agent_router_message (self); // If we're processing a request, dispatch to next server if (self->request) { if (s_clock () >= self->expires) { // Request expired, kill it zmsg_t *reply = zmsg_new ("FAILED"); zmsg_send (&reply, self->control); zmsg_destroy (&self->request); } else { // Find server to talk to, remove any expired ones while (zlist_size (self->actives)) { server_t *server = (server_t *) zlist_first (self->actives); if (s_clock () >= server->expires) { zlist_pop (self->actives); server->alive = 0; } else { zmsg_t *request = zmsg_dup (self->request); zmsg_push (request, server->endpoint); zmsg_send (&request, self->router); break; } } } } // Disconnect and delete any expired servers // Send heartbeats to idle servers if needed zhash_apply (self->servers, server_ping, self->router); } agent_destroy (&self); return NULL; }
size_t zmsg_size (zmsg_t *self) { assert (self); assert (zmsg_is (self)); return zlist_size (self->frames); }
static void freectx (void *arg) { ctx_t *ctx = arg; free_simstate (ctx->sim_state); while (zlist_size (ctx->queued_events) > 0) free (zlist_pop (ctx->queued_events)); zlist_destroy (&ctx->queued_events); while (zlist_size (ctx->running_jobs) > 0) free_job (zlist_pop (ctx->running_jobs)); zlist_destroy (&ctx->running_jobs); rdllib_close (ctx->rdllib); free (ctx->rdl); free (ctx); }
void subprocess_manager_destroy (struct subprocess_manager *sm) { size_t n = zlist_size (sm->processes); assert (n == 0); zlist_destroy (&sm->processes); free (sm); }