// Handle trigger requests from the sim module ("sim_exec.trigger") static void trigger_cb (flux_t *h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { json_t *o = NULL; const char *json_str = NULL; double next_termination = -1; zhash_t *job_hash = NULL; ctx_t *ctx = (ctx_t *)arg; if (flux_msg_get_string (msg, &json_str) < 0 || json_str == NULL || !(o = Jfromstr (json_str))) { flux_log (h, LOG_ERR, "%s: bad message", __FUNCTION__); return; } // Logging flux_log (h, LOG_DEBUG, "received a trigger (sim_exec.trigger: %s", json_str); // Handle the trigger ctx->sim_state = json_to_sim_state (o); handle_queued_events (ctx); #if SIMEXEC_IO job_hash = determine_all_min_bandwidth (ctx->rdl, ctx->running_jobs); #endif advance_time (ctx, job_hash); handle_completed_jobs (ctx); next_termination = determine_next_termination (ctx, ctx->sim_state->sim_time, job_hash); set_event_timer (ctx, "sim_exec", next_termination); send_reply_request (h, module_name, ctx->sim_state); // Cleanup free_simstate (ctx->sim_state); ctx->sim_state = NULL; Jput (o); zhash_destroy (&job_hash); }
int flux_modctl_list (flux_t h, const char *svc, const char *nodeset, flux_lsmod_f cb, void *arg) { JSON in = NULL; int rc = -1; uint32_t nodeid; flux_mrpc_t *mrpc = NULL; int errnum = 0; zhash_t *mods = NULL; if (!h || !cb) { errno = EINVAL; goto done; } if (!(mrpc = flux_mrpc_create (h, nodeset))) goto done; if (!(in = modctl_tlist_enc (svc))) goto done; flux_mrpc_put_inarg_obj (mrpc, in); if (flux_mrpc (mrpc, "modctl.list") < 0) goto done; flux_mrpc_rewind_outarg (mrpc); if (!(mods = zhash_new ())) oom (); while ((nodeid = flux_mrpc_next_outarg (mrpc)) != -1) { if (get_rlist_result (mods, mrpc, nodeid, &errnum) < 0) goto done; if (errnum) goto done; } if (cb_rlist_result (mods, cb, arg) < 0) goto done; rc = 0; done: zhash_destroy (&mods); if (mrpc) flux_mrpc_destroy (mrpc); Jput (in); if (errnum) errno = errnum; return rc; }
int maltcp_ctx_destroy(void **self_p) { clog_debug(maltcp_logger, "maltcp_ctx_destroy...\n"); if (self_p && *self_p) { maltcp_ctx_t *self = (maltcp_ctx_t *) *self_p; // TODO(AF): zmq_close versus zsocket_destroy zsocket_set_linger(self->endpoints_socket, 0); clog_debug(maltcp_logger, "maltcp_ctx_destroy: linger=%d\n", zsocket_linger(self->endpoints_socket)); zsocket_destroy(self->zmq_ctx, self->endpoints_socket); // zmq_close(mal_ctx->endpoints_socket); // Free all structures in hash-table, close socket and destroy mutex. if (self->cnx_table) { maltcp_ctx_connection_t *cnx_ptr = (maltcp_ctx_connection_t*) zhash_first(self->cnx_table); while (cnx_ptr) { // Close registered TCP connections clog_debug(maltcp_logger, "maltcp_ctx_destroy: close socket %d.\n", cnx_ptr->socket); maltcp_ctx_socket_destroy(cnx_ptr); // destroy all registered sockets cnx_ptr = (maltcp_ctx_connection_t*) zhash_next(self->cnx_table); } } // TODO (AF): Close all pollers? clog_debug(maltcp_logger, "maltcp_ctx_destroy: stopped.\n"); free(self->maltcp_header); // Free all structures in hash-table, close socket and destroy mutex. if (self->cnx_table) zhash_destroy(&self->cnx_table); zloop_destroy(&self->zloop); // zsocket_destroy(self->zmq_ctx, self->endpoints_socket); // zmq_close(self->endpoints_socket); zctx_destroy(&self->zmq_ctx); free(self); *self_p = NULL; } clog_debug(maltcp_logger, "maltcp_ctx_destroy: destroyed.\n"); return 0; }
void sprk_dataset_destroy (sprk_dataset_t **self_p) { assert (self_p); if (*self_p) { sprk_dataset_t *self = *self_p; block_t *block = (block_t *) zhash_first (self->blocks); while (block != NULL) { block_destroy (&block); zhash_delete (self->blocks, zhash_cursor (self->blocks)); block = (block_t *) zhash_next (self->blocks); } zhash_destroy (&self->blocks); // Free object itself free (self); *self_p = NULL; } }
void flux_handle_destroy (flux_t *hp) { if (hp) { flux_t h = *hp; if (h && --h->usecount == 0) { zhash_destroy (&h->aux); if (h->ops->impl_destroy) h->ops->impl_destroy (h->impl); tagpool_destroy (h->tagpool); if (h->dso) dlclose (h->dso); msglist_destroy (h->queue); if (h->pollfd >= 0) (void)close (h->pollfd); free (h); } *hp = NULL; } }
static void freectx (void *arg) { ctx_t *ctx = arg; zlist_t *keys = zhash_keys (ctx->ping_requests); char *key = zlist_first (keys); while (key) { zmsg_t *zmsg = zhash_lookup (ctx->ping_requests, key); zmsg_destroy (&zmsg); key = zlist_next (keys); } zlist_destroy (&keys); zhash_destroy (&ctx->ping_requests); zmsg_t *zmsg; while ((zmsg = zlist_pop (ctx->clog_requests))) zmsg_destroy (&zmsg); zlist_destroy (&ctx->clog_requests); free (ctx); }
zhash_t * zhash_new (void) { zhash_t *self = (zhash_t *) zmalloc (sizeof (zhash_t)); if (self) { self->prime_index = INITIAL_PRIME; self->chain_limit = INITIAL_CHAIN; size_t limit = primes [self->prime_index]; self->items = (item_t **) zmalloc (sizeof (item_t *) * limit); if (self->items) { self->hasher = s_bernstein_hash; self->key_destructor = (czmq_destructor *) zstr_free; self->key_duplicator = (czmq_duplicator *) strdup; self->key_comparator = (czmq_comparator *) strcmp; } else zhash_destroy (&self); } return self; }
void flux_handle_destroy (flux_t *h) { if (h && --h->usecount == 0) { zhash_destroy (&h->aux); if ((h->flags & FLUX_O_CLONE)) { flux_handle_destroy (h->parent); // decr usecount } else { if (h->ops->impl_destroy) h->ops->impl_destroy (h->impl); tagpool_destroy (h->tagpool); if (h->dso) dlclose (h->dso); msglist_destroy (h->queue); if (h->pollfd >= 0) (void)close (h->pollfd); } free (h); } }
static void client_destroy (client_t *c) { subscription_t *sub; ctx_t *ctx = c->ctx; if (c->disconnect_notify) { struct disconnect_notify *d; d = zhash_first (c->disconnect_notify); while (d) { disconnect_destroy (c, d); d = zhash_next (c->disconnect_notify); } zhash_destroy (&c->disconnect_notify); } if (c->subscriptions) { while ((sub = zlist_pop (c->subscriptions))) subscription_destroy (ctx->h, sub); zlist_destroy (&c->subscriptions); } if (c->uuid) zuuid_destroy (&c->uuid); if (c->outqueue) { flux_msg_t *msg; while ((msg = zlist_pop (c->outqueue))) flux_msg_destroy (msg); zlist_destroy (&c->outqueue); } flux_fd_watcher_stop (ctx->h, c->outw); flux_fd_watcher_destroy (c->outw); flux_msg_iobuf_clean (&c->outbuf); flux_fd_watcher_stop (ctx->h, c->inw); flux_fd_watcher_destroy (c->inw); flux_msg_iobuf_clean (&c->inbuf); if (c->fd != -1) close (c->fd); free (c); }
void zre_msg_destroy (zre_msg_t **self_p) { assert (self_p); if (*self_p) { zre_msg_t *self = *self_p; // Free class properties zframe_destroy (&self->routing_id); free (self->ipaddress); if (self->groups) zlist_destroy (&self->groups); zhash_destroy (&self->headers); zmsg_destroy (&self->content); free (self->group); // Free object itself free (self); *self_p = NULL; } }
void collabclient_free( void** ccvp ) { #ifdef BUILD_COLLAB cloneclient_t* cc = (cloneclient_t*)*ccvp; if( !cc ) return; if( cc->magic_number != MAGIC_VALUE ) { fprintf(stderr,"collabclient_free() called on an invalid client object!\n"); return; } cc->magic_number = MAGIC_VALUE + 1; { int fd = 0; size_t fdsz = sizeof(fd); int rc = zmq_getsockopt( cc->subscriber, ZMQ_FD, &fd, &fdsz ); GDrawRemoveReadFD( 0, fd, cc ); } zsocket_destroy( cc->ctx, cc->snapshot ); zsocket_destroy( cc->ctx, cc->subscriber ); zsocket_destroy( cc->ctx, cc->publisher ); BackgroundTimer_remove( cc->roundTripTimer ); FontView* fv = FontViewFind( FontViewFind_byCollabPtr, cc ); if( fv ) { fv->b.collabClient = 0; } zhash_destroy (&cc->kvmap); free(cc->address); free(cc); *ccvp = 0; #endif }
void zproto_example_destroy (zproto_example_t **self_p) { assert (self_p); if (*self_p) { zproto_example_t *self = *self_p; // Free class properties zframe_destroy (&self->routing_id); free (self->data); if (self->aliases) zlist_destroy (&self->aliases); zhash_destroy (&self->headers); zchunk_destroy (&self->public_key); zuuid_destroy (&self->identifier); zframe_destroy (&self->address); zmsg_destroy (&self->content); // Free object itself free (self); *self_p = NULL; } }
static void emit_command_help_from_pattern (const char *pattern, FILE *fp) { zhash_t *zh = NULL; zlist_t *keys = NULL; const char *cat; zh = get_command_list_hash (pattern); if (zh == NULL) return; keys = zhash_keys (zh); zlist_sort (keys, (zlist_compare_fn *) category_cmp); cat = zlist_first (keys); while (cat) { emit_command_list_category (zh, cat, fp); if ((cat = zlist_next (keys))) fprintf (fp, "\n"); } zlist_destroy (&keys); zhash_destroy (&zh); return; }
void zyre_peer_test (bool verbose) { printf (" * zyre_peer:"); zsock_t *mailbox = zsock_new_dealer ("@tcp://127.0.0.1:5551"); zhash_t *peers = zhash_new (); zuuid_t *you = zuuid_new (); zuuid_t *me = zuuid_new (); zyre_peer_t *peer = zyre_peer_new (peers, you); assert (!zyre_peer_connected (peer)); assert (!zyre_peer_connect (peer, me, "tcp://127.0.0.1:5551", 30000)); assert (zyre_peer_connected (peer)); zyre_peer_set_name (peer, "peer"); assert (streq (zyre_peer_name (peer), "peer")); zre_msg_t *msg = zre_msg_new (); zre_msg_set_id (msg, ZRE_MSG_HELLO); zre_msg_set_endpoint (msg, "tcp://127.0.0.1:5552"); int rc = zyre_peer_send (peer, &msg); assert (rc == 0); msg = zre_msg_new (); rc = zre_msg_recv (msg, mailbox); assert (rc == 0); if (verbose) zre_msg_print (msg); zre_msg_destroy (&msg); // Destroying container destroys all peers it contains zhash_destroy (&peers); zuuid_destroy (&me); zuuid_destroy (&you); zsock_destroy (&mailbox); printf ("OK\n"); }
zhash_t * zhash_dup_v2 (zhash_t *self) { if (!self) return NULL; zhash_t *copy = zhash_new (); if (copy) { zhash_autofree (copy); uint index; size_t limit = primes [self->prime_index]; for (index = 0; index < limit; index++) { item_t *item = self->items [index]; while (item) { if (zhash_insert (copy, item->key, item->value)) { zhash_destroy (©); break; } item = item->next; } } } return copy; }
int main (void) { // Prepare our context and subscriber zctx_t *ctx = zctx_new (); void *snapshot = zsocket_new (ctx, ZMQ_DEALER); zsocket_connect (snapshot, "tcp://localhost:5556"); void *subscriber = zsocket_new (ctx, ZMQ_SUB); zsockopt_set_subscribe (subscriber, ""); zsocket_connect (subscriber, "tcp://localhost:5557"); void *publisher = zsocket_new (ctx, ZMQ_PUSH); zsocket_connect (publisher, "tcp://localhost:5558"); zhash_t *kvmap = zhash_new (); srandom ((unsigned) time (NULL)); // Get state snapshot int64_t sequence = 0; zstr_send (snapshot, "ICANHAZ?"); while (TRUE) { kvmsg_t *kvmsg = kvmsg_recv (snapshot); if (!kvmsg) break; // Interrupted if (streq (kvmsg_key (kvmsg), "KTHXBAI")) { sequence = kvmsg_sequence (kvmsg); printf ("I: received snapshot=%d\n", (int) sequence); kvmsg_destroy (&kvmsg); break; // Done } kvmsg_store (&kvmsg, kvmap); } int64_t alarm = zclock_time () + 1000; while (!zctx_interrupted) { zmq_pollitem_t items [] = { { subscriber, 0, ZMQ_POLLIN, 0 } }; int tickless = (int) ((alarm - zclock_time ())); if (tickless < 0) tickless = 0; int rc = zmq_poll (items, 1, tickless * ZMQ_POLL_MSEC); if (rc == -1) break; // Context has been shut down if (items [0].revents & ZMQ_POLLIN) { kvmsg_t *kvmsg = kvmsg_recv (subscriber); if (!kvmsg) break; // Interrupted // Discard out-of-sequence kvmsgs, incl. heartbeats if (kvmsg_sequence (kvmsg) > sequence) { sequence = kvmsg_sequence (kvmsg); kvmsg_store (&kvmsg, kvmap); printf ("I: received update=%d\n", (int) sequence); } else kvmsg_destroy (&kvmsg); } // If we timed-out, generate a random kvmsg if (zclock_time () >= alarm) { kvmsg_t *kvmsg = kvmsg_new (0); kvmsg_fmt_key (kvmsg, "%d", randof (10000)); kvmsg_fmt_body (kvmsg, "%d", randof (1000000)); kvmsg_send (kvmsg, publisher); kvmsg_destroy (&kvmsg); alarm = zclock_time () + 1000; } } printf (" Interrupted\n%d messages in\n", (int) sequence); zhash_destroy (&kvmap); zctx_destroy (&ctx); return 0; }
static int s_agent_handle_pipe (agent_t *self) { // Get the whole message off the pipe in one go zmsg_t *request = zmsg_recv (self->pipe); char *command = zmsg_popstr (request); if (!command) return -1; // Interrupted if (streq (command, "ALLOW")) { char *address = zmsg_popstr (request); zhash_insert (self->whitelist, address, "OK"); zstr_free (&address); zstr_send (self->pipe, "OK"); } else if (streq (command, "DENY")) { char *address = zmsg_popstr (request); zhash_insert (self->blacklist, address, "OK"); zstr_free (&address); zstr_send (self->pipe, "OK"); } else if (streq (command, "PLAIN")) { // For now we don't do anything with domains char *domain = zmsg_popstr (request); zstr_free (&domain); // Get password file and load into zhash table // If the file doesn't exist we'll get an empty table char *filename = zmsg_popstr (request); zhash_destroy (&self->passwords); self->passwords = zhash_new (); zhash_load (self->passwords, filename); zstr_free (&filename); zstr_send (self->pipe, "OK"); } else if (streq (command, "CURVE")) { // For now we don't do anything with domains char *domain = zmsg_popstr (request); zstr_free (&domain); // If location is CURVE_ALLOW_ANY, allow all clients. Otherwise // treat location as a directory that holds the certificates. char *location = zmsg_popstr (request); if (streq (location, CURVE_ALLOW_ANY)) self->allow_any = true; else { zcertstore_destroy (&self->certstore); self->certstore = zcertstore_new (location); self->allow_any = false; } zstr_free (&location); zstr_send (self->pipe, "OK"); } else if (streq (command, "VERBOSE")) { char *verbose = zmsg_popstr (request); self->verbose = *verbose == '1'; zstr_free (&verbose); zstr_send (self->pipe, "OK"); } else if (streq (command, "TERMINATE")) { self->terminated = true; zstr_send (self->pipe, "OK"); } else { printf ("E: invalid command from API: %s\n", command); assert (false); } zstr_free (&command); zmsg_destroy (&request); return 0; }
void zyre_test (bool verbose) { printf (" * zyre: "); if (verbose) printf ("\n"); // @selftest // We'll use inproc gossip discovery so that this works without networking uint64_t version = zyre_version (); assert ((version / 10000) % 100 == ZYRE_VERSION_MAJOR); assert ((version / 100) % 100 == ZYRE_VERSION_MINOR); assert (version % 100 == ZYRE_VERSION_PATCH); // Create two nodes zyre_t *node1 = zyre_new ("node1"); assert (node1); assert (streq (zyre_name (node1), "node1")); zyre_set_header (node1, "X-HELLO", "World"); if (verbose) zyre_set_verbose (node1); // Set inproc endpoint for this node int rc = zyre_set_endpoint (node1, "inproc://zyre-node1"); assert (rc == 0); // Set up gossip network for this node zyre_gossip_bind (node1, "inproc://gossip-hub"); rc = zyre_start (node1); assert (rc == 0); zyre_t *node2 = zyre_new ("node2"); assert (node2); assert (streq (zyre_name (node2), "node2")); if (verbose) zyre_set_verbose (node2); // Set inproc endpoint for this node // First, try to use existing name, it'll fail rc = zyre_set_endpoint (node2, "inproc://zyre-node1"); assert (rc == -1); // Now use available name and confirm that it succeeds rc = zyre_set_endpoint (node2, "inproc://zyre-node2"); assert (rc == 0); // Set up gossip network for this node zyre_gossip_connect (node2, "inproc://gossip-hub"); rc = zyre_start (node2); assert (rc == 0); assert (strneq (zyre_uuid (node1), zyre_uuid (node2))); zyre_join (node1, "GLOBAL"); zyre_join (node2, "GLOBAL"); // Give time for them to interconnect zclock_sleep (250); if (verbose) zyre_dump (node1); zlist_t *peers = zyre_peers (node1); assert (peers); assert (zlist_size (peers) == 1); zlist_destroy (&peers); zyre_join (node1, "node1 group of one"); zyre_join (node2, "node2 group of one"); // Give them time to join their groups zclock_sleep (250); zlist_t *own_groups = zyre_own_groups (node1); assert (own_groups); assert (zlist_size (own_groups) == 2); zlist_destroy (&own_groups); zlist_t *peer_groups = zyre_peer_groups (node1); assert (peer_groups); assert (zlist_size (peer_groups) == 2); zlist_destroy (&peer_groups); char *value = zyre_peer_header_value (node2, zyre_uuid (node1), "X-HELLO"); assert (streq (value, "World")); zstr_free (&value); // One node shouts to GLOBAL zyre_shouts (node1, "GLOBAL", "Hello, World"); // Second node should receive ENTER, JOIN, and SHOUT zmsg_t *msg = zyre_recv (node2); assert (msg); char *command = zmsg_popstr (msg); assert (streq (command, "ENTER")); zstr_free (&command); assert (zmsg_size (msg) == 4); char *peerid = zmsg_popstr (msg); char *name = zmsg_popstr (msg); assert (streq (name, "node1")); zstr_free (&name); zframe_t *headers_packed = zmsg_pop (msg); char *address = zmsg_popstr (msg); char *endpoint = zyre_peer_address (node2, peerid); assert (streq (address, endpoint)); zstr_free (&peerid); zstr_free (&endpoint); zstr_free (&address); assert (headers_packed); zhash_t *headers = zhash_unpack (headers_packed); assert (headers); zframe_destroy (&headers_packed); assert (streq ((char *) zhash_lookup (headers, "X-HELLO"), "World")); zhash_destroy (&headers); zmsg_destroy (&msg); msg = zyre_recv (node2); assert (msg); command = zmsg_popstr (msg); assert (streq (command, "JOIN")); zstr_free (&command); assert (zmsg_size (msg) == 3); zmsg_destroy (&msg); msg = zyre_recv (node2); assert (msg); command = zmsg_popstr (msg); assert (streq (command, "JOIN")); zstr_free (&command); assert (zmsg_size (msg) == 3); zmsg_destroy (&msg); msg = zyre_recv (node2); assert (msg); command = zmsg_popstr (msg); assert (streq (command, "SHOUT")); zstr_free (&command); zmsg_destroy (&msg); zyre_stop (node2); msg = zyre_recv (node2); assert (msg); command = zmsg_popstr (msg); assert (streq (command, "STOP")); zstr_free (&command); zmsg_destroy (&msg); zyre_stop (node1); zyre_destroy (&node1); zyre_destroy (&node2); printf ("OK\n"); #ifdef ZYRE_BUILD_DRAFT_API if (zsys_has_curve()){ printf (" * zyre-curve: "); if (verbose) printf ("\n"); if (verbose) zsys_debug("----------------TESTING CURVE --------------"); zactor_t *speaker = zactor_new (zbeacon, NULL); assert (speaker); if (verbose) zstr_sendx (speaker, "VERBOSE", NULL); // ensuring we have a broadcast address zsock_send (speaker, "si", "CONFIGURE", 9999); char *hostname = zstr_recv (speaker); if (!*hostname) { printf ("OK (skipping test, no UDP broadcasting)\n"); zactor_destroy (&speaker); freen (hostname); return; } freen (hostname); zactor_destroy (&speaker); // zap setup zactor_t *auth = zactor_new(zauth, NULL); assert (auth); if (verbose) { zstr_sendx(auth, "VERBOSE", NULL); zsock_wait(auth); } zstr_sendx (auth, "CURVE", CURVE_ALLOW_ANY, NULL); zsock_wait (auth); zyre_t *node3 = zyre_new ("node3"); zyre_t *node4 = zyre_new ("node4"); assert (node3); assert (node4); zyre_set_verbose (node3); zyre_set_verbose (node4); zyre_set_zap_domain(node3, "TEST"); zyre_set_zap_domain(node4, "TEST"); zsock_set_rcvtimeo(node3->inbox, 10000); zsock_set_rcvtimeo(node4->inbox, 10000); zcert_t *node3_cert = zcert_new (); zcert_t *node4_cert = zcert_new (); assert (node3_cert); assert (node4_cert); zyre_set_zcert(node3, node3_cert); zyre_set_zcert(node4, node4_cert); zyre_set_header(node3, "X-PUBLICKEY", "%s", zcert_public_txt(node3_cert)); zyre_set_header(node4, "X-PUBLICKEY", "%s", zcert_public_txt(node4_cert)); // test beacon if (verbose) zsys_debug ("----------------TESTING BEACON----------------"); rc = zyre_start(node3); assert (rc == 0); rc = zyre_start(node4); assert (rc == 0); zyre_join (node3, "GLOBAL"); zyre_join (node4, "GLOBAL"); zclock_sleep (1500); if (verbose) { zyre_dump (node3); zyre_dump (node4); } zyre_shouts (node3, "GLOBAL", "Hello, World"); // Second node should receive ENTER, JOIN, and SHOUT msg = zyre_recv (node4); assert (msg); command = zmsg_popstr (msg); assert (streq (command, "ENTER")); zstr_free (&command); char *peerid = zmsg_popstr (msg); assert (peerid); name = zmsg_popstr (msg); assert (streq (name, "node3")); zmsg_destroy (&msg); msg = zyre_recv (node4); assert (msg); command = zmsg_popstr (msg); assert (streq (command, "JOIN")); zstr_free (&command); zmsg_destroy(&msg); msg = zyre_recv (node4); assert (msg); command = zmsg_popstr (msg); assert (streq (command, "SHOUT")); zstr_free (&command); zmsg_destroy(&msg); zyre_leave(node3, "GLOBAL"); zyre_leave(node4, "GLOBAL"); zstr_free (&name); zstr_free (&peerid); zstr_free (&command); zyre_stop (node3); zyre_stop (node4); // give things a chance to settle... zclock_sleep (250); zyre_destroy(&node3); zyre_destroy(&node4); zcert_destroy(&node3_cert); zcert_destroy(&node4_cert); // test gossip if (verbose) zsys_debug ("----------------TESTING GOSSIP----------------"); zyre_t *node5 = zyre_new ("node5"); zyre_t *node6 = zyre_new ("node6"); assert (node5); assert (node6); if (verbose) { zyre_set_verbose (node5); zyre_set_verbose (node6); } // if it takes more than 10s, something probably went terribly wrong zsock_set_rcvtimeo(node5->inbox, 10000); zsock_set_rcvtimeo(node6->inbox, 10000); zcert_t *node5_cert = zcert_new (); zcert_t *node6_cert = zcert_new (); assert (node5_cert); assert (node6_cert); zyre_set_zcert(node5, node5_cert); zyre_set_zcert(node6, node6_cert); zyre_set_header(node5, "X-PUBLICKEY", "%s", zcert_public_txt(node5_cert)); zyre_set_header(node6, "X-PUBLICKEY", "%s", zcert_public_txt(node6_cert)); const char *gossip_cert = zcert_public_txt (node5_cert); // TODO- need to add zyre_gossip_port functions to get port from gossip bind(?) zyre_gossip_bind(node5, "tcp://127.0.0.1:9001"); zyre_gossip_connect_curve(node6, gossip_cert, "tcp://127.0.0.1:9001"); zyre_start(node5); zsock_wait(node5); zyre_start(node6); zsock_wait(node6); zyre_join (node5, "GLOBAL"); zyre_join (node6, "GLOBAL"); // give things a chance to settle... zclock_sleep (1500); if (verbose) { zyre_dump (node5); zyre_dump (node6); } zyre_shouts (node5, "GLOBAL", "Hello, World"); // Second node should receive ENTER, JOIN, and SHOUT msg = zyre_recv (node6); assert (msg); command = zmsg_popstr (msg); zsys_info(command); assert (streq (command, "ENTER")); zstr_free (&command); peerid = zmsg_popstr (msg); assert (peerid); name = zmsg_popstr (msg); zmsg_destroy (&msg); assert (streq (name, "node5")); zstr_free (&name); zyre_leave(node5, "GLOBAL"); zyre_leave(node6, "GLOBAL"); zyre_stop (node5); zyre_stop (node6); // give things a chance to settle... zclock_sleep (250); zstr_free (&peerid); zcert_destroy (&node5_cert); zcert_destroy (&node6_cert); zyre_destroy(&node5); zyre_destroy(&node6); zactor_destroy(&auth); printf ("OK\n"); } #endif }
int main (int argc, char *argv[]) { struct context ctx; struct pmi_simple_ops ops = { .kvs_put = s_kvs_put, .kvs_get = s_kvs_get, .barrier_enter = s_barrier_enter, .response_send = s_send_response, }; struct pmi_simple_client *cli; int spawned = -1, initialized = -1; int rank = -1, size = -1; int universe_size = -1; int name_len = -1, key_len = -1, val_len = -1; char *name = NULL, *val = NULL, *val2 = NULL, *val3 = NULL; char *key = NULL; int rc; plan (NO_PLAN); if (!(ctx.kvs = zhash_new ())) oom (); ctx.size = 1; ok (socketpair (PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ctx.fds) == 0, "socketpair returned client,server file descriptors"); ctx.pmi = pmi_simple_server_create (&ops, 42, ctx.size, ctx.size, "bleepgorp", &ctx); ok (ctx.pmi != NULL, "created simple pmi server context"); ctx.buflen = pmi_simple_server_get_maxrequest (ctx.pmi); ctx.buf = xzmalloc (ctx.buflen); ok (pthread_create (&ctx.t, NULL, server_thread, &ctx) == 0, "pthread_create successfully started server"); setenvf ("PMI_FD", 1, "%d", ctx.fds[0]); setenvf ("PMI_RANK", 1, "%d", 0); setenvf ("PMI_SIZE", 1, "%d", ctx.size); ok ((cli = pmi_simple_client_create ()) != NULL, "pmi_simple_client_create OK"); ok (pmi_simple_client_initialized (cli, &initialized) == PMI_SUCCESS && initialized == 0, "pmi_simple_client_initialized OK, initialized=0"); ok (pmi_simple_client_init (cli, &spawned) == PMI_SUCCESS && spawned == 0, "pmi_simple_client_init OK, spawned=0"); ok (pmi_simple_client_initialized (cli, &initialized) == PMI_SUCCESS && initialized == 1, "pmi_simple_client_initialized OK, initialized=1"); /* retrieve basic params */ ok (pmi_simple_client_get_size (cli, &size) == PMI_SUCCESS && size == 1, "pmi_simple_client_get_size OK, size=%d", size); ok (pmi_simple_client_get_rank (cli, &rank) == PMI_SUCCESS && rank == 0, "pmi_simple_client_get_rank OK, rank=%d", rank); ok (pmi_simple_client_get_universe_size (cli, &universe_size) == PMI_SUCCESS && universe_size == size, "pmi_simple_client_get_universe_size OK, universe_size=%d", universe_size); ok (pmi_simple_client_kvs_get_name_length_max (cli, &name_len) == PMI_SUCCESS && name_len > 0, "pmi_simple_client_kvs_get_name_length_max OK, name_len=%d", name_len); ok (pmi_simple_client_kvs_get_key_length_max (cli, &key_len) == PMI_SUCCESS && key_len > 0, "pmi_simple_client_kvs_get_key_length_max OK, key_len=%d", key_len); ok (pmi_simple_client_kvs_get_value_length_max (cli, &val_len) == PMI_SUCCESS && val_len > 0, "pmi_simple_client_kvs_get_value_length_max OK, val_len=%d", val_len); name = xzmalloc (name_len); ok (pmi_simple_client_kvs_get_my_name (cli, name, name_len) == PMI_SUCCESS && strlen (name) > 0, "pmi_simple_client_kvs_get_my_name OK, name=%s", name); /* put foo=bar / commit / barier / get foo */ ok (pmi_simple_client_kvs_put (cli, name, "foo", "bar") == PMI_SUCCESS, "pmi_simple_client_kvs_put foo=bar OK"); ok (pmi_simple_client_kvs_commit (cli, name) == PMI_SUCCESS, "pmi_simple_client_kvs_commit OK"); ok (pmi_simple_client_barrier (cli) == PMI_SUCCESS, "pmi_simple_client_barrier OK"); val = xzmalloc (val_len); ok (pmi_simple_client_kvs_get (cli, name, "foo", val, val_len) == PMI_SUCCESS && !strcmp (val, "bar"), "pmi_simple_client_kvs_get foo OK, val=%s", val); /* put long=... / get long */ val2 = xzmalloc (val_len); memset (val2, 'x', val_len - 1); ok (pmi_simple_client_kvs_put (cli, name, "long", val2) == PMI_SUCCESS, "pmi_simple_client_kvs_put long=xxx... OK"); memset (val, 'y', val_len); /* not null terminated */ ok (pmi_simple_client_kvs_get (cli, name, "long", val, val_len) == PMI_SUCCESS && strnlen (val2, val_len) < val_len && strcmp (val, val2) == 0, "pmi_simple_client_kvs_get long OK, val=xxx..."); /* put: value too long */ val3 = xzmalloc (val_len + 1); memset (val3, 'y', val_len); rc = pmi_simple_client_kvs_put (cli, name, "toolong", val3); ok (rc == PMI_ERR_INVALID_VAL_LENGTH, "pmi_simple_client_kvs_put val too long fails"); /* put: key too long */ key = xzmalloc (key_len + 1); memset (key, 'z', key_len); rc = pmi_simple_client_kvs_put (cli, name, key, "abc"); ok (rc == PMI_ERR_INVALID_KEY_LENGTH, "pmi_simple_client_kvs_put key too long fails"); /* get: key too long */ rc = pmi_simple_client_kvs_get (cli, name, key, val, val_len); ok (rc == PMI_ERR_INVALID_KEY_LENGTH, "pmi_simple_client_kvs_get key too long fails"); /* get: no exist */ rc = pmi_simple_client_kvs_get (cli, name, "noexist", val, val_len); ok (rc == PMI_ERR_INVALID_KEY, "pmi_simple_client_kvs_get unknown key fails"); /* barrier: entry failure */ rig_barrier_entry_failure = 1; ok (pmi_simple_client_barrier (cli) == PMI_FAIL, "pmi_simple_client_barrier with entry function failure fails"); rig_barrier_entry_failure = 0; rig_barrier_exit_failure = 1; ok (pmi_simple_client_barrier (cli) == PMI_FAIL, "pmi_simple_client_barrier with exit function failure fails"); rig_barrier_exit_failure = 0; ok (pmi_simple_client_barrier (cli) == PMI_SUCCESS, "pmi_simple_client_barrier OK (rigged errors cleared)"); /* finalize */ ok (pmi_simple_client_finalize (cli) == PMI_SUCCESS, "pmi_simple_client_finalize OK"); ok (pthread_join (ctx.t, NULL) == 0, "pthread join successfully reaped server"); free (name); free (val); free (val2); free (val3); free (key); pmi_simple_client_destroy (cli); if (ctx.pmi) pmi_simple_server_destroy (ctx.pmi); close (ctx.fds[0]); close (ctx.fds[1]); zhash_destroy (&ctx.kvs); done_testing (); return 0; }
void skillsManagerFree(SkillsManager *self) { // Destroy hashtable of skills zhash_destroy (&self->skills); }
void zhash_test (int verbose) { printf (" * zhash: "); // @selftest zhash_t *hash = zhash_new (); assert (hash); assert (zhash_size (hash) == 0); // Insert some items int rc; rc = zhash_insert (hash, "DEADBEEF", "dead beef"); assert (rc == 0); rc = zhash_insert (hash, "ABADCAFE", "a bad cafe"); assert (rc == 0); rc = zhash_insert (hash, "C0DEDBAD", "coded bad"); assert (rc == 0); rc = zhash_insert (hash, "DEADF00D", "dead food"); assert (rc == 0); assert (zhash_size (hash) == 4); // Look for existing items char *item; item = (char *) zhash_lookup (hash, "DEADBEEF"); assert (streq (item, "dead beef")); item = (char *) zhash_lookup (hash, "ABADCAFE"); assert (streq (item, "a bad cafe")); item = (char *) zhash_lookup (hash, "C0DEDBAD"); assert (streq (item, "coded bad")); item = (char *) zhash_lookup (hash, "DEADF00D"); assert (streq (item, "dead food")); // Look for non-existent items item = (char *) zhash_lookup (hash, "foo"); assert (item == NULL); // Try to insert duplicate items rc = zhash_insert (hash, "DEADBEEF", "foo"); assert (rc == -1); item = (char *) zhash_lookup (hash, "DEADBEEF"); assert (streq (item, "dead beef")); // Rename an item rc = zhash_rename (hash, "DEADBEEF", "LIVEBEEF"); assert (rc == 0); rc = zhash_rename (hash, "WHATBEEF", "LIVEBEEF"); assert (rc == -1); // Test keys method zlist_t *keys = zhash_keys (hash); assert (zlist_size (keys) == 4); zlist_destroy (&keys); // Test dup method zhash_t *copy = zhash_dup (hash); assert (zhash_size (copy) == 4); item = (char *) zhash_lookup (copy, "LIVEBEEF"); assert (item); assert (streq (item, "dead beef")); zhash_destroy (©); // Test foreach assert (0 == zhash_foreach (hash, test_foreach, hash)); assert (-1 == zhash_foreach (hash, test_foreach_error, hash)); // Test save and load zhash_save (hash, ".cache"); copy = zhash_new (); zhash_load (copy, ".cache"); item = (char *) zhash_lookup (copy, "LIVEBEEF"); assert (item); assert (streq (item, "dead beef")); zhash_destroy (©); #if (defined (WIN32)) DeleteFile (".cache"); #else unlink (".cache"); #endif // Delete a item zhash_delete (hash, "LIVEBEEF"); item = (char *) zhash_lookup (hash, "LIVEBEEF"); assert (item == NULL); assert (zhash_size (hash) == 3); // Check that the queue is robust against random usage struct { char name [100]; bool exists; } testset [200]; memset (testset, 0, sizeof (testset)); int testmax = 200, testnbr, iteration; srandom ((unsigned) time (NULL)); for (iteration = 0; iteration < 25000; iteration++) { testnbr = randof (testmax); if (testset [testnbr].exists) { item = (char *) zhash_lookup (hash, testset [testnbr].name); assert (item); zhash_delete (hash, testset [testnbr].name); testset [testnbr].exists = false; } else { sprintf (testset [testnbr].name, "%x-%x", rand (), rand ()); if (zhash_insert (hash, testset [testnbr].name, "") == 0) testset [testnbr].exists = true; } } // Test 10K lookups for (iteration = 0; iteration < 10000; iteration++) item = (char *) zhash_lookup (hash, "DEADBEEFABADCAFE"); // Destructor should be safe to call twice zhash_destroy (&hash); zhash_destroy (&hash); assert (hash == NULL); // @end printf ("OK\n"); }
void ztns_test (bool verbose) { printf (" * ztns: "); // Strings ztns_t *tnetstr = ztns_new (); char *data_str = "Hello World!"; char *tnetstr_str = "12:Hello World!,"; int rc = ztns_append_str (tnetstr, data_str); assert (0 == rc); assert (streq (ztns_get (tnetstr), tnetstr_str)); char * index = tnetstr_str; char *result_str = (char *)ztns_parse (&index); assert (streq (index, "")); assert (streq (result_str, data_str)); free (result_str); ztns_destroy (&tnetstr); tnetstr = ztns_new (); char *data_empty_str = ""; char *tnetstr_empty_str = "0:,"; rc = ztns_append_str (tnetstr, data_empty_str); assert (0 == rc); assert (streq (ztns_get (tnetstr), tnetstr_empty_str)); index = tnetstr_empty_str; result_str = (char *)ztns_parse (&index); assert (streq (index, "")); assert (streq (result_str, data_empty_str)); free (result_str); ztns_destroy (&tnetstr); tnetstr = ztns_new (); char *data_tnet_str = "12:Hello World!,"; tnetstr_str = "16:12:Hello World!,,"; rc = ztns_append_str (tnetstr, data_tnet_str); assert (0 == rc); assert (streq (ztns_get (tnetstr), tnetstr_str)); index = tnetstr_str; result_str = (char *)ztns_parse (&index); assert (streq (index, "")); assert (streq (result_str, data_tnet_str)); free (result_str); ztns_destroy (&tnetstr); // Numbers tnetstr = ztns_new (); long long data_llong = 34; char *tnetstr_llong = "2:34#"; rc = ztns_append_llong (tnetstr, data_llong); assert (0 == rc); assert (streq (ztns_get (tnetstr), tnetstr_llong)); index = tnetstr_llong; long long *result_llong = (long long *)ztns_parse (&index); assert (streq (index, "")); assert (data_llong == *result_llong); free (result_llong); ztns_destroy (&tnetstr); tnetstr = ztns_new (); rc = ztns_append_llong (tnetstr, LLONG_MAX); assert (0 == rc); index = ztns_get (tnetstr); result_llong = (long long *)ztns_parse (&index); assert (streq (index, "")); assert (LLONG_MAX == *result_llong); free (result_llong); ztns_destroy (&tnetstr); tnetstr = ztns_new (); rc = ztns_append_llong (tnetstr, LLONG_MIN); assert (0 == rc); index = ztns_get (tnetstr); result_llong = (long long *)ztns_parse (&index); assert (streq (index, "")); assert (LLONG_MIN == *result_llong); free (result_llong); ztns_destroy (&tnetstr); char *tnetstr_llong_max_plus_one = "19:9223372036854775808#"; index = tnetstr_llong_max_plus_one; result_llong = (long long *)ztns_parse (&index); assert (NULL == result_llong); char *tnetstr_llong_min_minus_one = "20:-9223372036854775809#"; index = tnetstr_llong_min_minus_one; result_llong = (long long *)ztns_parse (&index); assert (NULL == result_llong); char *tnetstr_float_not_llong = "8:15.75331#"; index = tnetstr_float_not_llong; result_llong = (long long *)ztns_parse (&index); assert (NULL == result_llong); // Floats // ### These are a bastard to test and until there's a real use // I've got better things to do with my time //tnetstr = ztns_new (); //float data_float = 15.75331; //char *tnetstr_float = "8:15.75331^"; //rc = ztns_append_float (tnetstr, data_float); //assert (0 == rc); //assert (streq (ztns_get (tnetstr), tnetstr_float)); //index = tnetstr_float; //float *result_float = (float *)ztns_parse (&index); //assert (streq (index, "")); //assert (data_float == *result_float); //free (result_float); //ztns_destroy (&tnetstr); // Booleans tnetstr = ztns_new (); bool data_bool = true; char *tnetstr_bool = "4:true!"; rc = ztns_append_bool (tnetstr, data_bool); assert (0 == rc); assert (streq (ztns_get (tnetstr), tnetstr_bool)); index = tnetstr_bool; bool *result_bool = (bool *)ztns_parse (&index); assert (streq (index, "")); assert (data_bool == *result_bool); free (result_bool); ztns_destroy (&tnetstr); // NULL tnetstr = ztns_new (); char *tnetstr_null = "0:~"; rc = ztns_append_null (tnetstr); assert (streq (ztns_get (tnetstr), tnetstr_null)); index = tnetstr_null; void *result_null = ztns_parse (&index); assert (streq (index, "")); assert (NULL == result_null); ztns_destroy (&tnetstr); // Dictionaries zhash_t *dict = zhash_new (); zhash_t *empty_hash = zhash_new (); zlist_t *empty_list = zlist_new (); zhash_insert (dict, "STRING", data_str); zhash_insert (dict, "INTEGER", &data_llong); zhash_insert (dict, "BOOLEAN", &data_bool); zhash_insert (dict, "HASH", empty_hash); zhash_freefn (dict, "HASH", &s_zhash_free_fn); zhash_insert (dict, "LIST", empty_list); zhash_freefn (dict, "LIST", &s_zlist_free_fn); tnetstr = ztns_new (); rc = ztns_append_dict (tnetstr, dict, &s_tnetstr_foreach_dict_fn_test); assert (0 == rc); zhash_destroy (&dict); index = ztns_get (tnetstr); zhash_t *result_dict = (zhash_t *)ztns_parse (&index); assert (streq (index, "")); assert (NULL != result_dict); zhash_autofree (result_dict); char *item_str = (char *)zhash_lookup (result_dict, "STRING"); assert (streq (data_str, item_str)); long long *item_llong = (long long *)zhash_lookup (result_dict, "INTEGER"); assert (*item_llong == data_llong); bool *item_bool = (bool *)zhash_lookup (result_dict, "BOOLEAN"); assert (*item_bool == data_bool); zhash_t *item_hash = (zhash_t *)zhash_lookup (result_dict, "HASH"); assert (0 == zhash_size (item_hash)); zlist_t *item_list = (zlist_t *)zhash_lookup (result_dict, "LIST"); assert (0 == zlist_size (item_list)); zhash_destroy (&result_dict); ztns_destroy (&tnetstr); // Lists zlist_t *list = zlist_new (); empty_hash = zhash_new (); empty_list = zlist_new (); zlist_append (list, data_str); zlist_append (list, &data_llong); zlist_append (list, &data_bool); zlist_append (list, empty_hash); zlist_freefn (list, empty_hash, &s_zhash_free_fn, true); zlist_append (list, empty_list); zlist_freefn (list, empty_list, &s_zlist_free_fn, true); tnetstr = ztns_new (); rc = ztns_append_list (tnetstr, list, &s_tnetstr_foreach_list_fn_test); assert (0 == rc); zlist_destroy (&list); index = ztns_get (tnetstr); zlist_t *result_list = (zlist_t *)ztns_parse (&index); assert (streq (index, "")); assert (NULL != result_list); item_str = (char *)zlist_pop (result_list); assert (streq (data_str, item_str)); free (item_str); item_llong = (long long *)zlist_pop (result_list); assert (*item_llong == data_llong); free (item_llong); item_bool = (bool *)zlist_pop (result_list); assert (*item_bool == data_bool); free (item_bool); item_hash = (zhash_t *)zlist_pop (result_list); assert (0 == zhash_size (item_hash)); zhash_destroy (&item_hash); item_list = (zlist_t *)zlist_pop (result_list); assert (0 == zlist_size (item_list)); zlist_destroy (&item_list); zlist_destroy (&result_list); ztns_destroy (&tnetstr); printf ("OK\n"); }
int main (void) { zctx_t *context = zctx_new (); void *frontend = zsocket_new (context, ZMQ_SUB); zsocket_bind (frontend, "tcp://*:5557"); void *backend = zsocket_new (context, ZMQ_XPUB); zsocket_bind (backend, "tcp://*:5558"); // Subscribe to every single topic from publisher zsocket_set_subscribe (frontend, ""); // Store last instance of each topic in a cache zhash_t *cache = zhash_new (); // .split main poll loop // We route topic updates from frontend to backend, and // we handle subscriptions by sending whatever we cached, // if anything: while (true) { zmq_pollitem_t items [] = { { frontend, 0, ZMQ_POLLIN, 0 }, { backend, 0, ZMQ_POLLIN, 0 } }; if (zmq_poll (items, 2, 1000 * ZMQ_POLL_MSEC) == -1) break; // Interrupted // Any new topic data we cache and then forward if (items [0].revents & ZMQ_POLLIN) { char *topic = zstr_recv (frontend); char *current = zstr_recv (frontend); if (!topic) break; char *previous = zhash_lookup (cache, topic); if (previous) { zhash_delete (cache, topic); free (previous); } zhash_insert (cache, topic, current); zstr_sendm (backend, topic); zstr_send (backend, current); free (topic); } // .split handle subscriptions // When we get a new subscription we pull data from the cache: if (items [1].revents & ZMQ_POLLIN) { zframe_t *frame = zframe_recv (backend); if (!frame) break; // Event is one byte 0=unsub or 1=sub, followed by topic byte *event = zframe_data (frame); if (event [0] == 1) { char *topic = zmalloc (zframe_size (frame)); memcpy (topic, event + 1, zframe_size (frame) - 1); printf ("Sending cached topic %s\n", topic); char *previous = zhash_lookup (cache, topic); if (previous) { zstr_sendm (backend, topic); zstr_send (backend, previous); } free (topic); } zframe_destroy (&frame); } } zctx_destroy (&context); zhash_destroy (&cache); return 0; }
void s_zhash_free_fn (void *data) { zhash_t *hash = (zhash_t *)data; zhash_destroy (&hash); }
void * ztns_parse (char **p_tnetstr) { assert (p_tnetstr); if (NULL == p_tnetstr) return NULL; char * tnetstr = *p_tnetstr; assert (tnetstr); if (NULL == tnetstr) return NULL; char * colon = NULL; long int length = strtol (tnetstr, &colon, 10); if (0 == length && '0' != *tnetstr) return NULL; char type = *(colon + COLON_LENGTH + length); void * result = NULL; switch (type) { case ',': { char *str = (char *)malloc ((length + NULL_LENGTH) * sizeof(char)); assert (str); if (!str) { free (result); return NULL; } memcpy(str, colon + COLON_LENGTH, length); *(str + length) = '\0'; result = str; break; } case '#': { long long *number = malloc (sizeof(long long)); assert (number); if (!number) return NULL; char * check; *number = strtoll (colon + COLON_LENGTH, &check, 10); if (*check != type) { free (number); return NULL; } if (LLONG_MAX == *number) { uint llong_max_str_len = s_get_str_len (LLONG_MAX); char llong_max_str[llong_max_str_len + NULL_LENGTH]; snprintf (llong_max_str, llong_max_str_len + NULL_LENGTH, "%lld", LLONG_MAX); uint index = 0; while (*(colon + COLON_LENGTH + index) == *(llong_max_str + index)) { ++index; } if (('#' != *(colon + COLON_LENGTH + index)) || ('\0' != *(llong_max_str + index))) { free (number); return NULL; } } else if (LLONG_MIN == *number) { uint llong_min_str_len = s_get_str_len (LLONG_MIN); char llong_min_str[llong_min_str_len + NULL_LENGTH]; snprintf (llong_min_str, llong_min_str_len + NULL_LENGTH, "%lld", LLONG_MIN); uint index = 0; while (*(colon + COLON_LENGTH + index) == *(llong_min_str + index)) ++index; if (('#' != *(colon + COLON_LENGTH + index)) || ('\0' != *(llong_min_str + index))) { free (number); return NULL; } } result = number; break; } case '^': { float * flt = malloc (sizeof(float)); *flt = strtof (colon + COLON_LENGTH, NULL); result = flt; break; } case '!': { bool *boolean = malloc (sizeof(bool)); char first_char = *(colon + COLON_LENGTH); switch (first_char) { case 't': *boolean = true; break; case 'f': *boolean = false; break; default: free (boolean); return NULL; } result = boolean; break; } case '~': { // Nothing to do break; } case '}': { zhash_t *dict = zhash_new (); char * index = colon + COLON_LENGTH; while ('}' != *index) { if (index > (colon + COLON_LENGTH + length)) { zhash_destroy(&dict); return NULL; } char * key = ztns_parse (&index); if (!key) { zhash_destroy (&dict); return NULL; } void * item = ztns_parse (&index); if (!item) { zhash_destroy (&dict); return NULL; } int rc = zhash_insert (dict, key, item); // Apply the correct free function char item_type = *(index - TYPE_CHAR_LENGTH); switch (item_type) { case '}': if (NULL == zhash_freefn (dict, key, &s_free_dict)) { zhash_t *item_as_dict = (zhash_t *)item; zhash_destroy (&item_as_dict); zhash_destroy (&dict); return NULL; } break; case ']': if (NULL == zhash_freefn (dict, key, &s_free_list)) { zlist_t *item_as_list = (zlist_t *)item; zlist_destroy (&item_as_list); zhash_destroy (&dict); return NULL; } break; default: if (NULL == zhash_freefn (dict, key, &free)) { free (item); zhash_destroy (&dict); return NULL; } break; } // Free the key as we've taken a copy free (key); } result = dict; break; } case ']': { zlist_t *list = zlist_new (); char * index = colon + COLON_LENGTH; while (']' != *index) { if (index > (colon + COLON_LENGTH + length)) { zlist_destroy(&list); return NULL; } void * item = ztns_parse (&index); int rc = zlist_append (list, item); // Apply the correct free function char item_type = *(index - 1); switch (item_type) { case '}': if (NULL == zlist_freefn (list, item, &s_free_dict, true)) { zhash_t *item_as_dict = (zhash_t *)item; zhash_destroy (&item_as_dict); zlist_destroy (&list); return NULL; } break; case ']': if (NULL == zlist_freefn (list, item, &s_free_list, true)) { zlist_t *item_as_list = (zlist_t *)item; zlist_destroy (&item_as_list); zlist_destroy (&list); return NULL; } break; default: if (NULL == zlist_freefn (list, item, &free, true)) { free (item); zlist_destroy (&list); return NULL; } break; } } result = list; break; } default: return NULL; } *p_tnetstr = colon + COLON_LENGTH + length + TYPE_CHAR_LENGTH; return result; }
static void s_free_dict (void *data) { zhash_t *dict = (zhash_t *)data; zhash_destroy (&dict); }
void zyre_test (bool verbose) { printf (" * zyre: "); // @selftest // We'll use inproc gossip discovery so that this works without networking int major, minor, patch; zyre_version (&major, &minor, &patch); assert (major == ZYRE_VERSION_MAJOR); assert (minor == ZYRE_VERSION_MINOR); assert (patch == ZYRE_VERSION_PATCH); // Create two nodes zyre_t *node1 = zyre_new ("node1"); assert (node1); assert (streq (zyre_name (node1), "node1")); zyre_set_header (node1, "X-HELLO", "World"); zyre_set_verbose (node1); // Set inproc endpoint for this node zyre_set_endpoint (node1, "inproc://zyre-node1"); // Set up gossip network for this node zyre_gossip_bind (node1, "inproc://gossip-hub"); int rc = zyre_start (node1); assert (rc == 0); zyre_t *node2 = zyre_new ("node2"); assert (node2); assert (streq (zyre_name (node2), "node2")); zyre_set_verbose (node2); // Set inproc endpoint for this node // First, try to use existing name, it'll fail zyre_set_endpoint (node2, "inproc://zyre-node1"); assert (streq (zyre_endpoint (node2), "")); // Now use available name and confirm that it succeeds zyre_set_endpoint (node2, "inproc://zyre-node2"); assert (streq (zyre_endpoint (node2), "inproc://zyre-node2")); // Set up gossip network for this node zyre_gossip_connect (node2, "inproc://gossip-hub"); rc = zyre_start (node2); assert (rc == 0); assert (strneq (zyre_uuid (node1), zyre_uuid (node2))); zyre_join (node1, "GLOBAL"); zyre_join (node2, "GLOBAL"); // Give time for them to interconnect zclock_sleep (100); // One node shouts to GLOBAL zyre_shouts (node1, "GLOBAL", "Hello, World"); // Second node should receive ENTER, JOIN, and SHOUT zmsg_t *msg = zyre_recv (node2); assert (msg); char *command = zmsg_popstr (msg); assert (streq (command, "ENTER")); zstr_free (&command); assert (zmsg_size (msg) == 4); char *peerid = zmsg_popstr (msg); zstr_free (&peerid); char *name = zmsg_popstr (msg); assert (streq (name, "node1")); zstr_free (&name); zframe_t *headers_packed = zmsg_pop (msg); char *peeraddress = zmsg_popstr (msg); zstr_free (&peeraddress); assert (headers_packed); zhash_t *headers = zhash_unpack (headers_packed); assert (headers); zframe_destroy (&headers_packed); assert (streq ((char*)zhash_lookup (headers, "X-HELLO"), "World")); zhash_destroy (&headers); zmsg_destroy (&msg); msg = zyre_recv (node2); assert (msg); command = zmsg_popstr (msg); assert (streq (command, "JOIN")); zstr_free (&command); assert (zmsg_size (msg) == 3); zmsg_destroy (&msg); msg = zyre_recv (node2); assert (msg); command = zmsg_popstr (msg); assert (streq (command, "SHOUT")); zstr_free (&command); zmsg_destroy (&msg); zyre_stop (node1); zyre_stop (node2); zyre_destroy (&node1); zyre_destroy (&node2); // @end printf ("OK\n"); }
int main (void) { // Prepare our context and subscriber void *context = zmq_init (1); void *subscriber = zmq_socket (context, ZMQ_SUB); zmq_setsockopt (subscriber, ZMQ_SUBSCRIBE, "", 0); zmq_connect (subscriber, "tcp://localhost:5556"); void *snapshot = zmq_socket (context, ZMQ_XREQ); zmq_connect (snapshot, "tcp://localhost:5557"); void *updates = zmq_socket (context, ZMQ_PUSH); zmq_connect (updates, "tcp://localhost:5558"); s_catch_signals (); zhash_t *kvmap = zhash_new (); srandom ((unsigned) time (NULL)); // Get state snapshot int64_t sequence = 0; s_send (snapshot, "I can haz state?"); while (!s_interrupted) { kvmsg_t *kvmsg = kvmsg_recv (snapshot); if (!kvmsg) break; // Interrupted if (streq (kvmsg_key (kvmsg), "KTHXBAI")) { sequence = kvmsg_sequence (kvmsg); kvmsg_destroy (&kvmsg); break; // Done } kvmsg_store (&kvmsg, kvmap); } printf ("I: received snapshot=%" PRId64 "\n", sequence); int zero = 0; zmq_setsockopt (snapshot, ZMQ_LINGER, &zero, sizeof (zero)); zmq_close (snapshot); int64_t alarm = s_clock () + 1000; while (!s_interrupted) { zmq_pollitem_t items [] = { { subscriber, 0, ZMQ_POLLIN, 0 } }; int tickless = (int) ((alarm - s_clock ())); if (tickless < 0) tickless = 0; int rc = zmq_poll (items, 1, tickless * 1000); if (rc == -1) break; // Context has been shut down if (items [0].revents & ZMQ_POLLIN) { kvmsg_t *kvmsg = kvmsg_recv (subscriber); if (!kvmsg) break; // Interrupted // Discard out-of-sequence kvmsgs, incl. heartbeats if (kvmsg_sequence (kvmsg) > sequence) { sequence = kvmsg_sequence (kvmsg); kvmsg_store (&kvmsg, kvmap); printf ("I: received update=%" PRId64 "\n", sequence); } else kvmsg_destroy (&kvmsg); } // If we timed-out, generate a random kvmsg if (s_clock () >= alarm) { kvmsg_t *kvmsg = kvmsg_new (0); kvmsg_fmt_key (kvmsg, "%d", randof (10000)); kvmsg_fmt_body (kvmsg, "%d", randof (1000000)); kvmsg_send (kvmsg, updates); kvmsg_destroy (&kvmsg); alarm = s_clock () + 1000; } } zhash_destroy (&kvmap); printf (" Interrupted\n%" PRId64 " messages in\n", sequence); zmq_setsockopt (updates, ZMQ_LINGER, &zero, sizeof (zero)); zmq_close (updates); zmq_close (subscriber); zmq_term (context); return 0; }
void zhash_test (int verbose) { printf (" * zhash: "); // @selftest zhash_t *hash = zhash_new (); assert (hash); assert (zhash_size (hash) == 0); // Insert some items int rc; rc = zhash_insert (hash, "DEADBEEF", "dead beef"); assert (rc == 0); rc = zhash_insert (hash, "ABADCAFE", "a bad cafe"); assert (rc == 0); rc = zhash_insert (hash, "C0DEDBAD", "coded bad"); assert (rc == 0); rc = zhash_insert (hash, "DEADF00D", "dead food"); assert (rc == 0); assert (zhash_size (hash) == 4); // Look for existing items char *item; item = (char *) zhash_lookup (hash, "DEADBEEF"); assert (streq (item, "dead beef")); item = (char *) zhash_lookup (hash, "ABADCAFE"); assert (streq (item, "a bad cafe")); item = (char *) zhash_lookup (hash, "C0DEDBAD"); assert (streq (item, "coded bad")); item = (char *) zhash_lookup (hash, "DEADF00D"); assert (streq (item, "dead food")); // Look for non-existent items item = (char *) zhash_lookup (hash, "foo"); assert (item == NULL); // Try to insert duplicate items rc = zhash_insert (hash, "DEADBEEF", "foo"); assert (rc == -1); item = (char *) zhash_lookup (hash, "DEADBEEF"); assert (streq (item, "dead beef")); // Some rename tests // Valid rename, key is now LIVEBEEF rc = zhash_rename (hash, "DEADBEEF", "LIVEBEEF"); assert (rc == 0); item = (char *) zhash_lookup (hash, "LIVEBEEF"); assert (streq (item, "dead beef")); // Trying to rename an unknown item to a non-existent key rc = zhash_rename (hash, "WHATBEEF", "NONESUCH"); assert (rc == -1); // Trying to rename an unknown item to an existing key rc = zhash_rename (hash, "WHATBEEF", "LIVEBEEF"); assert (rc == -1); item = (char *) zhash_lookup (hash, "LIVEBEEF"); assert (streq (item, "dead beef")); // Trying to rename an existing item to another existing item rc = zhash_rename (hash, "LIVEBEEF", "ABADCAFE"); assert (rc == -1); item = (char *) zhash_lookup (hash, "LIVEBEEF"); assert (streq (item, "dead beef")); item = (char *) zhash_lookup (hash, "ABADCAFE"); assert (streq (item, "a bad cafe")); // Test keys method zlist_t *keys = zhash_keys (hash); assert (zlist_size (keys) == 4); zlist_destroy (&keys); // Test dup method zhash_t *copy = zhash_dup (hash); assert (zhash_size (copy) == 4); item = (char *) zhash_lookup (copy, "LIVEBEEF"); assert (item); assert (streq (item, "dead beef")); zhash_destroy (©); // Test pack/unpack methods zframe_t *frame = zhash_pack (hash); copy = zhash_unpack (frame); zframe_destroy (&frame); assert (zhash_size (copy) == 4); item = (char *) zhash_lookup (copy, "LIVEBEEF"); assert (item); assert (streq (item, "dead beef")); zhash_destroy (©); // Test foreach rc = zhash_foreach (hash, test_foreach, hash); assert (rc == 0); rc = zhash_foreach (hash, test_foreach_error, hash); assert (rc == -1); // Test save and load zhash_comment (hash, "This is a test file"); zhash_comment (hash, "Created by %s", "czmq_selftest"); zhash_save (hash, ".cache"); copy = zhash_new (); zhash_load (copy, ".cache"); item = (char *) zhash_lookup (copy, "LIVEBEEF"); assert (item); assert (streq (item, "dead beef")); zhash_destroy (©); zsys_file_delete (".cache"); // Delete a item zhash_delete (hash, "LIVEBEEF"); item = (char *) zhash_lookup (hash, "LIVEBEEF"); assert (item == NULL); assert (zhash_size (hash) == 3); // Check that the queue is robust against random usage struct { char name [100]; bool exists; } testset [200]; memset (testset, 0, sizeof (testset)); int testmax = 200, testnbr, iteration; srandom ((unsigned) time (NULL)); for (iteration = 0; iteration < 25000; iteration++) { testnbr = randof (testmax); if (testset [testnbr].exists) { item = (char *) zhash_lookup (hash, testset [testnbr].name); assert (item); zhash_delete (hash, testset [testnbr].name); testset [testnbr].exists = false; } else { sprintf (testset [testnbr].name, "%x-%x", rand (), rand ()); if (zhash_insert (hash, testset [testnbr].name, "") == 0) testset [testnbr].exists = true; } } // Test 10K lookups for (iteration = 0; iteration < 10000; iteration++) item = (char *) zhash_lookup (hash, "DEADBEEFABADCAFE"); // Destructor should be safe to call twice zhash_destroy (&hash); zhash_destroy (&hash); assert (hash == NULL); // Test autofree; automatically copies and frees string values hash = zhash_new (); zhash_autofree (hash); char value [255]; strcpy (value, "This is a string"); rc = zhash_insert (hash, "key1", value); assert (rc == 0); strcpy (value, "Ring a ding ding"); rc = zhash_insert (hash, "key2", value); assert (rc == 0); assert (streq ((char *) zhash_lookup (hash, "key1"), "This is a string")); assert (streq ((char *) zhash_lookup (hash, "key2"), "Ring a ding ding")); zhash_destroy (&hash); // @end printf ("OK\n"); }
static void layer_info_destroy(layer_info_t * linfo) { zhash_vmap_values(linfo->buffers, buffer_info_destroy); zhash_destroy(linfo->buffers); free(linfo); }