int main (void) { clonesrv_t *self = (clonesrv_t *) zmalloc (sizeof (clonesrv_t)); self->port = 5556; self->ctx = zctx_new (); self->kvmap = zhash_new (); self->loop = zloop_new (); zloop_set_verbose (self->loop, FALSE); // Set up our clone server sockets self->snapshot = zsocket_new (self->ctx, ZMQ_ROUTER); self->publisher = zsocket_new (self->ctx, ZMQ_PUB); self->collector = zsocket_new (self->ctx, ZMQ_PULL); zsocket_bind (self->snapshot, "tcp://*:%d", self->port); zsocket_bind (self->publisher, "tcp://*:%d", self->port + 1); zsocket_bind (self->collector, "tcp://*:%d", self->port + 2); // Register our handlers with reactor zmq_pollitem_t poller = { self->snapshot, 0, ZMQ_POLLIN }; zloop_poller (self->loop, &poller, s_snapshots, self); poller.socket = self->collector; zloop_poller (self->loop, &poller, s_collector, self); zloop_timer (self->loop, 1000, 0, s_flush_ttl, self); // Run reactor until process interrupted zloop_start (self->loop); zloop_destroy (&self->loop); zhash_destroy (&self->kvmap); zctx_destroy (&self->ctx); free (self); return 0; }
/* url subtitle arguments */ int main (int argc, char *argv []) { void *context = zmq_init (1); void *subscriber = zmq_socket (context, ZMQ_SUB); size_t title_len = 0; assert(zmq_connect (subscriber, argv[1]) == 0); assert(title_len = strlen(argv[2]) > 1); assert(zmq_setsockopt (subscriber, ZMQ_SUBSCRIBE, argv[2], title_len) == 0); Bool verbose = 0; zloop_t *loop = zloop_new (); assert (loop); zloop_set_verbose (loop, verbose); zmq_pollitem_t sub_event = { subscriber, 0, ZMQ_POLLIN }; if ( argc > 3 ) { assert(zloop_poller (loop, &sub_event, subscriber_cb, (void*)(argv + 3)) == 0); } else { assert(zloop_poller (loop, &sub_event, subscriber_cb, NULL) == 0); } zloop_start (loop); zloop_destroy (&loop); assert (loop == NULL); zmq_close (subscriber); zmq_term (context); return 0; }
int main (int argc, char** argv) { int port = 5556; #ifdef FF_USE_LIBGC GC_INIT(); set_program_name (argv[0]); #endif if( argc >= 2 ) port = atoi( argv[1] ); clonesrv_t *self = (clonesrv_t *) zmalloc (sizeof (clonesrv_t)); self->port = port; self->ctx = zctx_new (); self->kvmap = zhash_new (); self->loop = zloop_new (); zloop_set_verbose (self->loop, false); // Set up our clone server sockets self->snapshot = zsocket_new (self->ctx, ZMQ_ROUTER); zsocket_bind (self->snapshot, "tcp://*:%d", self->port + socket_srv_offset_snapshot ); self->publisher = zsocket_new (self->ctx, ZMQ_PUB); zsocket_bind (self->publisher, "tcp://*:%d", self->port + socket_srv_offset_publisher ); self->collector = zsocket_new (self->ctx, ZMQ_PULL); zsocket_bind (self->collector, "tcp://*:%d", self->port + socket_srv_offset_collector ); self->ping = zsocket_new (self->ctx, ZMQ_REP); zsocket_bind (self->ping, "tcp://*:%d", self->port + socket_srv_offset_ping ); // Register our handlers with reactor zmq_pollitem_t poller = { 0, 0, ZMQ_POLLIN }; poller.socket = self->snapshot; zloop_poller (self->loop, &poller, s_snapshots, self); poller.socket = self->collector; zloop_poller (self->loop, &poller, s_collector, self); zloop_timer (self->loop, 1000, 0, s_flush_ttl, self); poller.socket = self->ping; zloop_poller (self->loop, &poller, s_ping, self); DEBUG ("I: server up and running on port:%d...", port ); // Run reactor until process interrupted zloop_start (self->loop); zloop_destroy (&self->loop); zhash_destroy (&self->kvmap); zctx_destroy (&self->ctx); free (self); return 0; }
bstar_t * bstar_new (int primary, char *local, char *remote) { bstar_t *self; self = (bstar_t *) zmalloc (sizeof (bstar_t)); // Initialize the Binary Star self->ctx = zctx_new (); self->loop = zloop_new (); self->state = primary? STATE_PRIMARY: STATE_BACKUP; // Create publisher for state going to peer self->statepub = zsocket_new (self->ctx, ZMQ_PUB); zsocket_bind (self->statepub, local); // Create subscriber for state coming from peer self->statesub = zsocket_new (self->ctx, ZMQ_SUB); zsocket_set_subscribe (self->statesub, ""); zsocket_connect (self->statesub, remote); // Set-up basic reactor events zloop_timer (self->loop, BSTAR_HEARTBEAT, 0, s_send_state, self); zmq_pollitem_t poller = { self->statesub, 0, ZMQ_POLLIN }; zloop_poller (self->loop, &poller, s_recv_state, self); return self; }
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); } } }
// 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; }
int bstar_voter(bstar_t *self, char *endpoint, int type, zloop_fn handler, void *arg) { void *socket = zsocket_new(self->ctx, type); zsocket_bind(socket, endpoint); assert(!self->voter_fn); self->voter_fn = handler; self->voter_arg = arg; zmq_pollitem_t poller = {socket, 0, ZMQ_POLLIN}; return zloop_poller(self->loop, &poller, s_voter_ready, self); }
int main(int argc, char const * const *argv) { int rc; zsys_set_sndhwm(1); zsys_set_linger(100); void *pusher = zsock_new(ZMQ_PUSH); assert(pusher); zsock_set_sndhwm(pusher, 1000); zsock_set_linger(pusher, 500); rc = zsock_connect(pusher, "tcp://localhost:12345"); assert(rc==0); void *puller = zsock_new(ZMQ_PULL); assert(puller); zsock_set_rcvhwm(puller, 1000); zsock_set_linger(puller, 500); rc = zsock_bind(puller, "tcp://*:12345"); if (rc != 12345){ printf("bind failed: %s\n", zmq_strerror(errno)); } assert(rc == 12345); void *publisher = zsock_new(ZMQ_PUB); assert(publisher); zsock_set_sndhwm(publisher, 1000); zsock_set_linger(publisher, 500); rc = zsock_bind(publisher, "tcp://*:12346"); assert(rc==12346); // set up event loop zloop_t *loop = zloop_new(); assert(loop); zloop_set_verbose(loop, 0); // push data every 10 ms rc = zloop_timer(loop, 1, 0, timer_event, pusher); assert(rc != -1); zmq_pollitem_t item; item.socket = puller; item.events = ZMQ_POLLIN; rc = zloop_poller(loop, &item, forward, publisher); assert(rc == 0); rc = zloop_start(loop); printf("zloop return: %d", rc); zloop_destroy(&loop); assert(loop == NULL); return 0; }
static void peering_poller (peering_t *self, int events) { driver_t *driver = self->driver; if (self->events != events) { zmq_pollitem_t item = { NULL, self->handle, events, 0 }; zloop_poller_end (driver->loop, &item); if (events) zloop_poller (driver->loop, &item, s_peering_activity, self); self->events = events; } }
static int s_new_slave (zloop_t *loop, zmq_pollitem_t *unused, void *args) { clonesrv_t *self = (clonesrv_t *) args; zhash_destroy (&self->kvmap); self->master = FALSE; self->slave = TRUE; zmq_pollitem_t poller = { self->subscriber, 0, ZMQ_POLLIN }; zloop_poller (bstar_zloop (self->bstar), &poller, s_subscriber, self); return 0; }
static vocket_t * vocket_new (driver_t *driver, int socktype, char *vtxname) { assert (driver); vocket_t *self = (vocket_t *) zmalloc (sizeof (vocket_t)); self->driver = driver; self->vtxname = strdup (vtxname); self->binding_hash = zhash_new (); self->peering_hash = zhash_new (); self->peering_list = zlist_new (); self->live_peerings = zlist_new (); self->socktype = socktype; uint index; for (index = 0; index < tblsize (s_vocket_config); index++) if (socktype == s_vocket_config [index].socktype) break; if (index < tblsize (s_vocket_config)) { self->routing = s_vocket_config [index].routing; self->nomnom = s_vocket_config [index].nomnom; self->min_peerings = s_vocket_config [index].min_peerings; self->max_peerings = s_vocket_config [index].max_peerings; } else { zclock_log ("E: invalid vocket type %d", socktype); exit (1); } // Create msgpipe vocket and connect over inproc to vtxname self->msgpipe = zsocket_new (driver->ctx, ZMQ_PAIR); assert (self->msgpipe); zsocket_connect (self->msgpipe, "inproc://%s", vtxname); // If we drop on no peerings, start routing input now if (self->min_peerings == 0) { // Ask reactor to start monitoring vocket's msgpipe pipe zmq_pollitem_t item = { self->msgpipe, 0, ZMQ_POLLIN, 0 }; zloop_poller (driver->loop, &item, s_vocket_input, self); } // Store this vocket per driver so that driver can cleanly destroy // all its vockets when it is destroyed. zlist_push (driver->vockets, self); //* Start transport-specific work self->inbuf_max = VTX_TCP_INBUF_MAX; self->outbuf_max = VTX_TCP_OUTBUF_MAX; //* End transport-specific work return self; }
maltcp_ctx_connection_t *maltcp_ctx_socket_connect(maltcp_ctx_t *self, mal_uri_t *socket_uri) { maltcp_ctx_connection_t *cnx_ptr = (maltcp_ctx_connection_t *) zhash_lookup(self->cnx_table, socket_uri); if (cnx_ptr == NULL) { clog_debug(maltcp_logger, "maltcp_ctx_socket_connect: open a new PTP socket\n"); // Create a new connection struct hostent *server; int client_socket = socket(AF_INET, SOCK_STREAM, 0); if (client_socket == -1) { clog_error(maltcp_logger, "maltcp_ctx_socket_connect: failed to create client socket: %s\n", strerror(errno)); return NULL; } char *ipaddr = maltcp_get_host_from_uri(socket_uri); int port = maltcp_get_port_from_uri(socket_uri); clog_debug(maltcp_logger, "maltcp_ctx_socket_connect: %s %d\n", ipaddr, port); if ((server = gethostbyname(ipaddr)) == NULL) { clog_error(maltcp_logger, "maltcp_ctx_socket_connect: failed to to get address: %s\n", strerror(errno)); free(ipaddr); return NULL; } free(ipaddr); struct sockaddr_in server_addr; bzero((char *) &server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&server_addr.sin_addr.s_addr, server->h_length); server_addr.sin_port = htons(port); if (connect(client_socket, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) { clog_error(maltcp_logger, "maltcp_ctx_socket_connect: failed to connect: %s\n", strerror(errno)); return NULL; } clog_debug(maltcp_logger, "maltcp_ctx_socket_connect: connected to %s\n", socket_uri); clog_debug(maltcp_logger, "maltcp_ctx_socket_connect: update TCP connections table\n"); cnx_ptr = maltcp_ctx_connection_register_outgoing(self, client_socket, socket_uri); // Register a zloop poller for this connection. zmq_pollitem_t poller = { NULL, client_socket, ZMQ_POLLIN }; int rc = zloop_poller(self->zloop, &poller, maltcp_ctx_socket_receive, self); assert(rc == 0); } else { clog_debug(maltcp_logger, "maltcp_ctx_socket_connect: use existing connection (%d) for %s\n", cnx_ptr->socket, socket_uri); } return cnx_ptr; }
static driver_t * driver_new (zctx_t *ctx, void *pipe) { driver_t *self = (driver_t *) zmalloc (sizeof (driver_t)); self->ctx = ctx; self->pipe = pipe; self->vockets = zlist_new (); self->loop = zloop_new (); self->scheme = VTX_TCP_SCHEME; // Reactor starts by monitoring the driver control pipe zmq_pollitem_t item = { self->pipe, 0, ZMQ_POLLIN }; zloop_poller (self->loop, &item, s_driver_control, self); return self; }
static int s_new_passive (zloop_t *loop, zmq_pollitem_t *unused, void *args) { clonesrv_t *self = (clonesrv_t *) args; zhash_destroy (&self->kvmap); self->active = false; self->passive = true; // Start subscribing to updates zmq_pollitem_t poller = { self->subscriber, 0, ZMQ_POLLIN }; zloop_poller (bstar_zloop (self->bstar), &poller, s_subscriber, self); return 0; }
// This function is called when an incoming connection is detected on the // listening socket. It accepts the connection and registers the appropriate // poller to receive message. int maltcp_ctx_socket_accept(zloop_t *zloop, zmq_pollitem_t *poller, void *arg) { maltcp_ctx_t *self = (maltcp_ctx_t *) arg; clog_debug(maltcp_logger, "maltcp_ctx: TCP server socket accept.\n"); if (self->mal_socket == -1) { // The context is closed, return clog_debug(maltcp_logger, "maltcp_ctx_socket_accept: socket (%d) closed\n", poller->fd); return -1; } // Accept incoming connection and register it. struct sockaddr src_addr; int new_socket = -1; socklen_t len = sizeof(struct sockaddr_in); // Note: May be we could use poller->fd to replace self->mal_socket if ((new_socket = accept(self->mal_socket, &src_addr, &len)) == -1) { clog_error(maltcp_logger, "Failed to accept: %s\n", strerror(errno)); return -1; } if (clog_is_loggable(maltcp_logger, CLOG_DEBUG_LEVEL)) { // Needed only for debug. char src_ipstr[INET6_ADDRSTRLEN]; int src_port; if (src_addr.sa_family == AF_INET) { struct sockaddr_in *s = (struct sockaddr_in *)&src_addr; src_port = ntohs(s->sin_port); inet_ntop(AF_INET, &s->sin_addr, src_ipstr, sizeof src_ipstr); } else { // AF_INET6 struct sockaddr_in6 *s = (struct sockaddr_in6 *)&src_addr; src_port = ntohs(s->sin6_port); inet_ntop(AF_INET6, &s->sin6_addr, src_ipstr, sizeof src_ipstr); } clog_debug(maltcp_logger, "maltcp_ctx_socket_accept: Source URI: %s%s:%d\n", MALTCP_URI, src_ipstr, src_port); } zmq_pollitem_t poller2 = { NULL, new_socket, ZMQ_POLLIN }; int rc = zloop_poller(zloop, &poller2, maltcp_ctx_socket_receive, self); assert(rc == 0); // Note: do not register the connection since the uri is not yet precisely known. clog_debug(maltcp_logger, "maltcp_ctx: TCP connection established.\n"); return 0; }
void rabbitmq_listener(zsock_t *pipe, void* args) { set_thread_name("rabbit-consumer"); // signal readyiness immediately so that zmq publishers are already processed // while the rabbitmq exchanges/queues/bindings are created zsock_signal(pipe, 0); amqp_connection_state_t conn = setup_amqp_connection(); int last_channel = rabbitmq_setup_queues(conn, (zlist_t*)args); // connect to the receiver socket zsock_t *receiver = zsock_new(ZMQ_PUSH); zsock_set_sndhwm(receiver, 10000); zsock_connect(receiver, "inproc://receiver"); // set up event loop zloop_t *loop = zloop_new(); assert(loop); zloop_set_verbose(loop, 0); zloop_ignore_interrupts(loop); // register actor command handler int rc = zloop_reader(loop, pipe, pipe_command, NULL); assert(rc==0); // register rabbitmq socket for pollin events zmq_pollitem_t rabbit_item = { .fd = amqp_get_sockfd(conn), .events = ZMQ_POLLIN }; rabbit_listener_state_t listener_state = { .conn = conn, .receiver = zsock_resolve(receiver) }; rc = zloop_poller(loop, &rabbit_item, rabbitmq_consume_message_and_forward, &listener_state); assert(rc==0); // start event loop zloop_start(loop); // shutdown zloop_destroy(&loop); zsock_destroy(&receiver); shutdown_amqp_connection(conn, 0, last_channel); }
void start_loop(int count) { zloop_t *loop = zloop_new(); assert(loop); zmq_pollitem_t poll_socket = { dealer, 0, ZMQ_POLLIN, 0 }; zloop_poller ( loop, &poll_socket, event, NULL); zloop_timer(loop, 1000, 0, sleep_loop, &count); zloop_timer(loop, 1000, 0, info_loop, &count); struct timeval tv; gettimeofday(&tv,NULL); start = (uint64_t)tv.tv_sec; zloop_start (loop); return; }
int main(void) { zctx_t *ctx = zctx_new(); lbbroker_t *self = (lbbroker_t *)zmalloc(sizeof(lbbroker_t)); self->frontend = zsocket_new(ctx, ZMQ_ROUTER); self->backend = zsocket_new(ctx, ZMQ_ROUTER); #if (defined (WIN32)) zsocket_bind(self->frontend, "tcp://*:5672"); // frontend zsocket_bind(self->backend, "tcp://*:5673"); // backend #else zsocket_bind(self->frontend, "ipc://frontend.ipc"); zsocket_bind(self->backend, "ipc://backend.ipc"); #endif int client_nbr; for (client_nbr = 0; client_nbr < NBR_CLIENTS; client_nbr++) zthread_new(client_task, NULL); int worker_nbr; for (worker_nbr = 0; worker_nbr < NBR_WORKERS; worker_nbr++) zthread_new(worker_task, NULL); // Queue of available workers self->workers = zlist_new(); // Prepare reactor and fire it up zloop_t *reactor = zloop_new(); zmq_pollitem_t poller = { self->backend, 0, ZMQ_POLLIN }; zloop_poller(reactor, &poller, s_handle_backend, self); zloop_start(reactor); zloop_destroy(&reactor); // When we're done, clean up properly while (zlist_size(self->workers)) { zframe_t *frame = (zframe_t *)zlist_pop(self->workers); zframe_destroy(&frame); } zlist_destroy(&self->workers); zctx_destroy(&ctx); free(self); return 0; }
void zloop_test (bool verbose) { printf (" * zloop: "); int rc = 0; // @selftest zctx_t *ctx = zctx_new (); assert (ctx); void *output = zsocket_new (ctx, ZMQ_PAIR); assert (output); zsocket_bind (output, "inproc://zloop.test"); void *input = zsocket_new (ctx, ZMQ_PAIR); assert (input); zsocket_connect (input, "inproc://zloop.test"); zloop_t *loop = zloop_new (); assert (loop); zloop_set_verbose (loop, verbose); // Create a timer that will be canceled int timer_id = zloop_timer (loop, 1000, 1, s_timer_event, NULL); zloop_timer (loop, 5, 1, s_cancel_timer_event, &timer_id); // After 20 msecs, send a ping message to output zloop_timer (loop, 20, 1, s_timer_event, output); // When we get the ping message, end the reactor zmq_pollitem_t poll_input = { input, 0, ZMQ_POLLIN }; rc = zloop_poller (loop, &poll_input, s_socket_event, NULL); assert (rc == 0); zloop_set_tolerant (loop, &poll_input); zloop_start (loop); zloop_destroy (&loop); assert (loop == NULL); zctx_destroy (&ctx); // @end printf ("OK\n"); }
int main (int argc, char *argv []) { if (argc == 2) { count = atoi(argv[1]); } zctx_t *ctx = zctx_new(); void *client = zsocket_new(ctx, ZMQ_ROUTER); zloop_t *loop = zloop_new(); zsocket_bind(client, "ipc:///tmp/zmqtestbr"); zmq_pollitem_t items [] = { { client, 0, ZMQ_POLLIN, 0 } }; zloop_poller(loop, items, recvHandler, client); zloop_start(loop); zloop_destroy(&loop); zctx_destroy(&ctx); return 0; }
bstar_t * bstar_new(int primary, char *local, char *remote) { bstar_t *self; self = (bstar_t *)zmalloc(sizeof(bstar_t)); self->ctx = zctx_new(); self->loop = zloop_new(); self->state = primary ? STATE_PRIMARY : STATE_BACKUP; self->statepub = zsocket_new(self->ctx, ZMQ_PUB); zsocket_bind(self->statepub, local); self->statesub = zsocket_new(self->ctx, ZMQ_SUB); zsocket_set_subscribe(self->statesub, ""); zsocket_connect(self->statesub, remote); zloop_timer(self->loop, BSTAR_HEARTBEAT, 0, s_send_state, self); zmq_pollitem_t poller = {self->statesub, 0, ZMQ_POLLIN}; zloop_poller(self->loop, &poller, s_recv_state, self); return self; }
static void forkzio_pipe_thd (void *args, zctx_t *zctx, void *zs) { forkzio_t ctx = args; zmq_pollitem_t zp = { .fd = -1, .socket = zs, .events = ZMQ_POLLIN }; zloop_t *zloop; pid_t pid; if (!(zloop = zloop_new ())) oom (); /* child stdin <= zs */ zloop_poller (zloop, &zp, (zloop_fn *)forkzio_zsock_cb, ctx); ctx->zio[0] = zio_pipe_writer_create ("stdin", NULL); if (zio_zloop_attach (ctx->zio[0], zloop) < 0) err_exit ("zio_zloop_attach %s", zio_name (ctx->zio[0])); /* child stdout => zs */ ctx->zio[1] = zio_pipe_reader_create ("stdout", zs, ctx); zio_set_close_cb (ctx->zio[1], forkzio_close_cb); if (zio_zloop_attach (ctx->zio[1], zloop) < 0) err_exit ("zio_zloop_attach %s", zio_name (ctx->zio[1])); ctx->readers++; /* child stderr => zs */ ctx->zio[2] = zio_pipe_reader_create ("stderr", zs, ctx); zio_set_close_cb (ctx->zio[2], forkzio_close_cb); if (zio_zloop_attach (ctx->zio[2], zloop) < 0) err_exit ("zio_zloop_attach %s", zio_name (ctx->zio[2])); ctx->readers++; pid = forkzio_fork (ctx); (void)zloop_start (zloop); forkzio_wait (pid); zio_destroy (ctx->zio[0]); zio_destroy (ctx->zio[1]); zio_destroy (ctx->zio[2]); zstr_send (zs, ""); /* signify EOF by sending an empty message */ } static void forkzio_pty_thd (void *args, zctx_t *zctx, void *zs) { forkzio_t ctx = args; zmq_pollitem_t zp = { .fd = -1, .socket = zs, .events = ZMQ_POLLIN }; zloop_t *zloop; pid_t pid; int ptyfd; if (!(zloop = zloop_new ())) oom (); switch ((pid = forkpty (&ptyfd, NULL, NULL, NULL))) { case -1: /* error */ err_exit ("forkpty"); case 0: /* child */ (void)execvp (ctx->av[0], ctx->av); err_exit ("%s", ctx->av[0]); default: /* parent */ break; } /* Data read from zs is written to pty master */ zloop_poller (zloop, &zp, (zloop_fn *)forkzio_zsock_cb, ctx); ctx->zio[0] = zio_writer_create ("stdin", ptyfd, NULL); zio_set_unbuffered (ctx->zio[0]); if (zio_zloop_attach (ctx->zio[0], zloop) < 0) err_exit ("zio_zloop_attach %s", zio_name (ctx->zio[0])); /* Data read from pty master is written to zs */ ctx->zio[1] = zio_reader_create ("stdout", ptyfd, zs, ctx); zio_set_unbuffered (ctx->zio[1]); zio_set_close_cb (ctx->zio[1], forkzio_close_cb); if (zio_zloop_attach (ctx->zio[1], zloop) < 0) err_exit ("zio_zloop_attach %s", zio_name (ctx->zio[1])); ctx->readers++; (void)zloop_start (zloop); forkzio_wait (pid); zio_destroy (ctx->zio[0]); zio_destroy (ctx->zio[1]); zstr_send (zs, ""); /* signify EOF by sending an empty message */ } forkzio_t forkzio_open (zctx_t *zctx, int ac, char **av, int flags) { zthread_attached_fn *thd = forkzio_pipe_thd; forkzio_t ctx = xzmalloc (sizeof (*ctx)); ctx->ac = ac; ctx->av = av; ctx->zctx = zctx; ctx->flags = flags; if ((ctx->flags & FORKZIO_FLAG_PTY)) thd = forkzio_pty_thd; if (!(ctx->zs = zthread_fork (zctx, thd, ctx))) { free (ctx); ctx = NULL; } return ctx; }
/// // Register low-level libzmq pollitem with the reactor. When the pollitem // is ready, will call the handler, passing the arg. Returns 0 if OK, -1 // if there was an error. If you register the pollitem more than once, each // instance will invoke its corresponding handler. A pollitem with // socket=NULL and fd=0 means 'poll on FD zero'. int QmlZloop::poller (zmq_pollitem_t *item, zloop_fn handler, void *arg) { return zloop_poller (self, item, handler, arg); };
int main (int argc, char *argv []) { clonesrv_t *self = (clonesrv_t *) zmalloc (sizeof (clonesrv_t)); if (argc == 2 && streq (argv [1], "-p")) { zclock_log ("I: primary master, waiting for backup (slave)"); self->bstar = bstar_new (BSTAR_PRIMARY, "tcp://*:5003", "tcp://localhost:5004"); bstar_voter (self->bstar, "tcp://*:5556", ZMQ_ROUTER, s_snapshots, self); self->port = 5556; self->peer = 5566; self->primary = TRUE; } else if (argc == 2 && streq (argv [1], "-b")) { zclock_log ("I: backup slave, waiting for primary (master)"); self->bstar = bstar_new (BSTAR_BACKUP, "tcp://*:5004", "tcp://localhost:5003"); bstar_voter (self->bstar, "tcp://*:5566", ZMQ_ROUTER, s_snapshots, self); self->port = 5566; self->peer = 5556; self->primary = FALSE; } else { printf ("Usage: clonesrv4 { -p | -b }\n"); free (self); exit (0); } // Primary server will become first master if (self->primary) self->kvmap = zhash_new (); self->ctx = zctx_new (); self->pending = zlist_new (); bstar_set_verbose (self->bstar, TRUE); // Set up our clone server sockets self->publisher = zsocket_new (self->ctx, ZMQ_PUB); self->collector = zsocket_new (self->ctx, ZMQ_SUB); zsockopt_set_subscribe (self->collector, ""); zsocket_bind (self->publisher, "tcp://*:%d", self->port + 1); zsocket_bind (self->collector, "tcp://*:%d", self->port + 2); // Set up our own clone client interface to peer self->subscriber = zsocket_new (self->ctx, ZMQ_SUB); zsockopt_set_subscribe (self->subscriber, ""); zsocket_connect (self->subscriber, "tcp://localhost:%d", self->peer + 1); // Register state change handlers bstar_new_master (self->bstar, s_new_master, self); bstar_new_slave (self->bstar, s_new_slave, self); // Register our other handlers with the bstar reactor zmq_pollitem_t poller = { self->collector, 0, ZMQ_POLLIN }; zloop_poller (bstar_zloop (self->bstar), &poller, s_collector, self); zloop_timer (bstar_zloop (self->bstar), 1000, 0, s_flush_ttl, self); zloop_timer (bstar_zloop (self->bstar), 1000, 0, s_send_hugz, self); // Start the Bstar reactor bstar_start (self->bstar); // Interrupted, so shut down while (zlist_size (self->pending)) { kvmsg_t *kvmsg = (kvmsg_t *) zlist_pop (self->pending); kvmsg_destroy (&kvmsg); } zlist_destroy (&self->pending); bstar_destroy (&self->bstar); zhash_destroy (&self->kvmap); zctx_destroy (&self->ctx); free (self); return 0; }
static binding_t * binding_require (vocket_t *vocket, char *address) { assert (vocket); binding_t *self = (binding_t *) zhash_lookup (vocket->binding_hash, address); if (self == NULL) { // Create new binding for this hostname:port address self = (binding_t *) zmalloc (sizeof (binding_t)); self->vocket = vocket; self->driver = vocket->driver; self->address = strdup (address); driver_t *driver = self->driver; // Split port number off address char *port = strchr (address, ':'); assert (port); *port++ = 0; //* Start transport-specific work // Create new bound TCP socket handle self->handle = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if (self->handle == -1) derp ("socket"); // Get sockaddr_in structure for address struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons (atoi (port)); // Bind handle to specific local address, or * if (streq (address, "*")) addr.sin_addr.s_addr = htonl (INADDR_ANY); else if (inet_aton (address, &addr.sin_addr) == 0) { zclock_log ("E: bind failed: invalid address '%s'", address); self->exception = TRUE; } if (!self->exception) { # ifndef __WINDOWS__ // On POSIX systems we need to set SO_REUSEADDR to reuse an // address without a 5-minute timeout. On win32 this option // lets you bind to an in-use address, so we do not do that. int reuse = 1; setsockopt (self->handle, SOL_SOCKET, SO_REUSEADDR, (void *) &reuse, sizeof (reuse)); # endif if (bind (self->handle, (const struct sockaddr *) &addr, IN_ADDR_SIZE) == -1) { zclock_log ("E: bind failed: '%s'", strerror (errno)); self->exception = TRUE; } else if (listen (self->handle, VTX_TCP_BACKLOG)) { zclock_log ("E: listen failed: '%s'", strerror (errno)); self->exception = TRUE; } } if (self->exception) close (self->handle); else { // Ask reactor to start monitoring this binding handle zmq_pollitem_t item = { NULL, self->handle, ZMQ_POLLIN, 0 }; zloop_poller (driver->loop, &item, s_binding_input, vocket); } //* End transport-specific work if (self->exception) { free (self->address); free (self); self = NULL; } else { // Store new binding in vocket containers zhash_insert (vocket->binding_hash, address, self); zhash_freefn (vocket->binding_hash, address, binding_delete); if (driver->verbose) zclock_log ("I: (tcp) create binding to %s", self->address); } } return self; }
int main (int argc, char *argv []) { clonesrv_t *self = (clonesrv_t *) zmalloc (sizeof (clonesrv_t)); if (argc == 2 && streq (argv [1], "-p")) { zclock_log ("I: primary active, waiting for backup (passive)"); self->bstar = bstar_new (BSTAR_PRIMARY, "tcp://*:5003", "tcp://localhost:5004"); bstar_voter (self->bstar, "tcp://*:5556", ZMQ_ROUTER, s_snapshots, self); self->port = 5556; self->peer = 5566; self->primary = true; } else if (argc == 2 && streq (argv [1], "-b")) { zclock_log ("I: backup passive, waiting for primary (active)"); self->bstar = bstar_new (BSTAR_BACKUP, "tcp://*:5004", "tcp://localhost:5003"); bstar_voter (self->bstar, "tcp://*:5566", ZMQ_ROUTER, s_snapshots, self); self->port = 5566; self->peer = 5556; self->primary = false; } else { printf ("Usage: clonesrv4 { -p | -b }\n"); free (self); exit (0); } // Primary server will become first active if (self->primary) self->kvmap = zhash_new (); self->ctx = zctx_new (); self->pending = zlist_new (); bstar_set_verbose (self->bstar, true); // Set up our clone server sockets self->publisher = zsocket_new (self->ctx, ZMQ_PUB); self->collector = zsocket_new (self->ctx, ZMQ_SUB); zsocket_set_subscribe (self->collector, ""); zsocket_bind (self->publisher, "tcp://*:%d", self->port + 1); zsocket_bind (self->collector, "tcp://*:%d", self->port + 2); // Set up our own clone client interface to peer self->subscriber = zsocket_new (self->ctx, ZMQ_SUB); zsocket_set_subscribe (self->subscriber, ""); zsocket_connect (self->subscriber, "tcp://localhost:%d", self->peer + 1); // .split main task body // After we've setup our sockets, we register our binary star // event handlers, and then start the bstar reactor. This finishes // when the user presses Ctrl-C or when the process receives a SIGINT // interrupt: // Register state change handlers bstar_new_active (self->bstar, s_new_active, self); bstar_new_passive (self->bstar, s_new_passive, self); // Register our other handlers with the bstar reactor zmq_pollitem_t poller = { self->collector, 0, ZMQ_POLLIN }; zloop_poller (bstar_zloop (self->bstar), &poller, s_collector, self); zloop_timer (bstar_zloop (self->bstar), 1000, 0, s_flush_ttl, self); zloop_timer (bstar_zloop (self->bstar), 1000, 0, s_send_hugz, self); // Start the bstar reactor bstar_start (self->bstar); // Interrupted, so shut down while (zlist_size (self->pending)) { kvmsg_t *kvmsg = (kvmsg_t *) zlist_pop (self->pending); kvmsg_destroy (&kvmsg); } zlist_destroy (&self->pending); bstar_destroy (&self->bstar); zhash_destroy (&self->kvmap); zctx_destroy (&self->ctx); free (self); return 0; }
/// // Register low-level libzmq pollitem with the reactor. When the pollitem // is ready, will call the handler, passing the arg. Returns 0 if OK, -1 // if there was an error. If you register the pollitem more than once, each // instance will invoke its corresponding handler. A pollitem with // socket=NULL and fd=0 means 'poll on FD zero'. int QZloop::poller (zmq_pollitem_t *item, zloop_fn handler, void *arg) { int rv = zloop_poller (self, item, handler, arg); return rv; }
maltcp_ctx_t *maltcp_ctx_new(mal_ctx_t *mal_ctx, char *hostname, char *port, maltcp_header_t *maltcp_header, // TODO: no longer used bool verbose) { maltcp_ctx_t *self = (maltcp_ctx_t *) malloc(sizeof(maltcp_ctx_t)); if (!self) return NULL; self->mal_ctx = mal_ctx; self->hostname = hostname; self->port = port; self->maltcp_header = maltcp_header; self->encoder = malbinary_encoder_new(true); self->decoder = malbinary_decoder_new(true); self->root_uri = (char *) malloc(strlen(hostname) + strlen(port) + 10 + 1); sprintf((char*) self->root_uri, "%s%s:%s", MALTCP_URI, hostname, port); clog_debug(maltcp_logger, "maltcp_ctx_new: root_uri=%s\n", self->root_uri); zctx_t *zmq_ctx = zctx_new(); self->zmq_ctx = zmq_ctx; self->cnx_table = zhash_new(); // Creates the TCP listening socket int listen = maltcp_ctx_server_socket_create(atoi(port), BACKLOG); //assert(listen >= 0); if (listen < 0) { clog_error(maltcp_logger, "EXCEPTION:: maltcp_ctx_new: listen = %d\n", listen); return NULL; } self->mal_socket = listen; clog_debug(maltcp_logger, "maltcp_ctx: ptp listening to: %s\n", port); //inproc void *endpoints_socket = zsocket_new(zmq_ctx, ZMQ_ROUTER); self->endpoints_socket = endpoints_socket; zsocket_bind(endpoints_socket, ZLOOP_ENDPOINTS_SOCKET_URI); zloop_t *zloop = zloop_new(); // TODO (AF): It seems that adding poller from outside of handler is not correctly // supported by ZMQ. We should provide an inproc socket allowing to add the needed // poller. However it seems that a timer regularly awaking the zloop corrects this // issue. zloop_timer(zloop, 100, 0, zloop_timer_handle, self); // zloop_set_verbose(zloop, true); self->zloop = zloop; zmq_pollitem_t poller = { NULL, listen, ZMQ_POLLIN }; int rc = zloop_poller(zloop, &poller, maltcp_ctx_socket_accept, self); assert(rc == 0); mal_ctx_set_binding( mal_ctx, self, maltcp_ctx_create_uri, maltcp_ctx_create_endpoint, maltcp_ctx_destroy_endpoint, maltcp_ctx_create_poller, maltcp_ctx_destroy_poller, maltcp_ctx_poller_add_endpoint, maltcp_ctx_poller_del_endpoint, maltcp_ctx_send_message, maltcp_ctx_recv_message, maltcp_ctx_poller_wait, maltcp_ctx_destroy_message, maltcp_ctx_start, maltcp_ctx_stop, maltcp_ctx_destroy); return self; }
void PrimeWorker::Work(zctx_t *ctx, void *pipe) { printf("PrimeWorker started.\n"); mBackend = zsocket_new(ctx, ZMQ_DEALER); void* frontend = zsocket_new(ctx, ZMQ_DEALER); void* input = zsocket_new(ctx, ZMQ_SUB); mServer = zsocket_new(ctx, ZMQ_ROUTER); mSignals = zsocket_new(ctx, ZMQ_PUB); zsocket_set_sndhwm(mBackend, 1*1000*1000); int err = 0; err = zsocket_bind(mServer, "tcp://*:%d", mServerPort); if(!err) printf("zsocket_bind(mServer, tcp://*:*) failed.\n"); err = zsocket_bind(mSignals, "tcp://*:%d", mSignalPort); if(!err) printf("zsocket_bind(mSignals, tcp://*:*) failed.\n"); printf("PrimeWorker: mServerPort=%d mSignalPort=%d\n", mServerPort, mSignalPort); err = zsocket_connect(mBackend, "tcp://localhost:8888"); assert(!err); err = zsocket_connect(frontend, "tcp://localhost:7777"); assert(!err); err = zsocket_connect(input, "inproc://bitcoin"); assert(!err); const char one[2] = {1, 0}; zsocket_set_subscribe(input, one); zloop_t* wloop = zloop_new(); zmq_pollitem_t item_input = {input, 0, ZMQ_POLLIN, 0}; err = zloop_poller(wloop, &item_input, &PrimeWorker::InvokeInput, this); assert(!err); zmq_pollitem_t item_server = {mServer, 0, ZMQ_POLLIN, 0}; err = zloop_poller(wloop, &item_server, &PrimeWorker::InvokeRequest, this); assert(!err); zmq_pollitem_t item_frontend = {frontend, 0, ZMQ_POLLIN, 0}; err = zloop_poller(wloop, &item_frontend, &PrimeWorker::InvokeRequest, this); assert(!err); err = zloop_timer(wloop, 60000, 0, &PrimeWorker::InvokeTimerFunc, this); assert(err >= 0); zsocket_signal(pipe); zloop_start(wloop); zloop_destroy(&wloop); zsocket_destroy(ctx, mServer); zsocket_destroy(ctx, mSignals); zsocket_destroy(ctx, mBackend); zsocket_destroy(ctx, frontend); zsocket_destroy(ctx, input); zsocket_signal(pipe); printf("PrimeWorker exited.\n"); }
int main(void) { gBlock.set_height(0); gClientName = sysinfo::GetClientName(); gClientID = sysinfo::GetClientID(); gInstanceID = gClientID * (unsigned)time(0); srand(gInstanceID); std::string frontHost; unsigned frontPort; Configuration* cfg = Configuration::create(); try{ cfg->parse("config.txt"); frontHost = cfg->lookupString("", "server", "localhost"); frontPort = cfg->lookupInt("", "port", 6666); gAddr = cfg->lookupString("", "address", ""); gClientName = cfg->lookupString("", "name", gClientName.c_str()); }catch(const ConfigurationException& ex){ printf("ERROR: %s\n", ex.c_str()); printf("hit return to exit...\n"); std::string line; std::getline(std::cin, line); exit(EXIT_FAILURE); } if(!gClientName.size()) gClientName = sysinfo::GetClientName(); printf("madPrimeMiner-v%d.%d\n", gClientVersion/10, gClientVersion%10); printf("ClientName = '%s' ClientID = %u InstanceID = %u\n", gClientName.c_str(), gClientID, gInstanceID); printf("Address = '%s'\n", gAddr.c_str()); if(!gAddr.size()){ printf("ERROR: address not specified in config.txt\n"); printf("hit return to exit...\n"); std::string line; std::getline(std::cin, line); exit(EXIT_FAILURE); } gCtx = zctx_new(); gWorkers = zsocket_new(gCtx, ZMQ_PULL); zsocket_bind(gWorkers, "inproc://shares"); gClient = new XPMClient(gCtx); gExit = !gClient->Initialize(cfg); while(!gExit){ printf("Connecting to frontend: %s:%d ...\n", frontHost.c_str(), frontPort); gBlock.Clear(); proto::Reply rep; gExit = true; while(gExit){ zsocket_destroy(gCtx, gFrontend); gFrontend = zsocket_new(gCtx, ZMQ_DEALER); int err = zsocket_connect(gFrontend, "tcp://%s:%d", frontHost.c_str(), frontPort); if(err){ printf("ERROR: invalid hostname and/or port.\n"); exit(EXIT_FAILURE); } proto::Request req; req.set_type(proto::Request::CONNECT); req.set_reqid(++gNextReqID); req.set_version(gClientVersion); req.set_height(0); GetNewReqNonce(req); Send(req, gFrontend); bool ready = zsocket_poll(gFrontend, 3*1000); if(zctx_interrupted) break; if(!ready) continue; Receive(rep, gFrontend); if(rep.error() != proto::Reply::NONE){ printf("ERROR: %s\n", proto::Reply::ErrType_Name(rep.error()).c_str()); if(rep.has_errstr()) printf("Message from server: %s\n", rep.errstr().c_str()); } if(!rep.has_sinfo()) break; gServerInfo = rep.sinfo(); bool ret = false; ret |= !ConnectBitcoin(); ret |= !ConnectSignals(); if(ret) break; gExit = false; } zsocket_disconnect(gFrontend, "tcp://%s:%d", frontHost.c_str(), frontPort); if(gExit) break; zloop_t* wloop = zloop_new(); zmq_pollitem_t item_server = {gServer, 0, ZMQ_POLLIN, 0}; int err = zloop_poller(wloop, &item_server, &HandleReply, 0); assert(!err); zmq_pollitem_t item_signals = {gSignals, 0, ZMQ_POLLIN, 0}; err = zloop_poller(wloop, &item_signals, &HandleSignal, 0); assert(!err); zmq_pollitem_t item_workers = {gWorkers, 0, ZMQ_POLLIN, 0}; err = zloop_poller(wloop, &item_workers, &HandleWorkers, 0); assert(!err); err = zloop_timer(wloop, 60*1000, 0, &HandleTimer, 0); assert(err >= 0); gHeartBeat = true; gExit = true; if(rep.has_block()) HandleNewBlock(rep.block()); else RequestWork(); gClient->Toggle(); zloop_start(wloop); gClient->Toggle(); zloop_destroy(&wloop); zsocket_destroy(gCtx, gServer); zsocket_destroy(gCtx, gSignals); gServer = 0; gSignals = 0; } delete gClient; zsocket_destroy(gCtx, gWorkers); zsocket_destroy(gCtx, gFrontend); zctx_destroy(&gCtx); return EXIT_SUCCESS; }