int main (int argc, char **argv) { int opt; char *configfile = "hosts"; JRB hosts, node, node2; Host *host, *join, *me; int nhosts; int i, j; Message *m; char dest[160]; char msg[256]; Key tmp; ChimeraHost ch; double start; while ((opt = getopt (argc, argv, OPTSTR)) != EOF) { switch ((char) opt) { case 'f': configfile = optarg; break; default: fprintf (stderr, "invalid option %c\n", (char) opt); fprintf (stderr, "usage: %s\n", USAGE); exit (1); } } sem = sema_create (0); state = (ChimeraState *) malloc (sizeof (ChimeraState)); me = (Host *) malloc (sizeof (Host)); me->name = "localhost"; me->port = 11110; me->hnp = "localhost:11110"; hosts = read_hosts (configfile, &nhosts); state->log = log_init (); log_direct (state->log, LOG_ERROR, stderr); log_direct (state->log, LOG_WARN, stderr); key_init (); state->message = message_init (state, 11110); message_handler (state, 21, hello, 1); message_handler (state, 22, fwd, 1); message_handler (state, 23, del, 1); message_handler (state, 24, NULL, 1); srand (time (NULL)); /* This part runs bighost in different hosts */ announced = 0; jrb_traverse (node, hosts) { if (announced == 0) { join = NULL; } else { i = (rand () % announced) + 1; jrb_traverse (node2, hosts) { i--; if (i == 0) break; } join = (Host *) node2->val.v; } host = (Host *) node->val.v; start_host (host, join); dsleep (0.1); }
//----------------------------------------------------------------------------- // When the SIGINT signal is received, we need to start shutting down the // service. This means that it needs to: // 1. Close the listening socket. // 2. Send a CLOSING message to every connected node. // 3. if there are any undelivered messages in the queues, we need to return them. // 4. Shutdown the nodes if we can. // 5. Shutdown the queues if we can. // 6. Tell the stats system to close its event as soon as there are no more nodes connected. void sigint_handler(evutil_socket_t fd, short what, void *arg) { system_data_t *sysdata = (system_data_t *) arg; server_t *server; stats_t *stats; queue_t *q; node_t *node; controller_t *ct; logger(sysdata->logging, 3, "SIGINT"); assert(sysdata); assert(sysdata->servers); // delete the sigint event, we dont need it anymore. assert(sysdata->sigint_event); event_free(sysdata->sigint_event); sysdata->sigint_event = NULL; // delete the sighup event, we dont need that either. assert(sysdata->sighup_event); event_free(sysdata->sighup_event); sysdata->sighup_event = NULL; // delete the sigusr1 event, we dont need that either. assert(sysdata->sigusr1_event); event_free(sysdata->sigusr1_event); sysdata->sigusr1_event = NULL; // delete the sigusr2 event, we dont need that either. assert(sysdata->sigusr2_event); event_free(sysdata->sigusr2_event); sysdata->sigusr2_event = NULL; logger(sysdata->logging, 2, "Shutting down servers."); while ((server = ll_pop_head(sysdata->servers))) { server_shutdown(server); server_free(server); free(server); } // All active nodes should be informed that we are shutting down. logger(sysdata->logging, 2, "Shutting down nodes."); assert(sysdata->nodelist); ll_start(sysdata->nodelist); while ((node = ll_next(sysdata->nodelist))) { assert(node->handle > 0); logger(sysdata->logging, 2, "Initiating shutdown of node %d.", node->handle); node_shutdown(node); } ll_finish(sysdata->nodelist); // Now attempt to shutdown all the queues. Basically, this just means that the queue will close down all the 'waiting' consumers. logger(sysdata->logging, 2, "Initiating shutdown of queues."); ll_start(sysdata->queues); while ((q = ll_next(sysdata->queues))) { assert(q->name != NULL); assert(q->qid > 0); logger(sysdata->logging, 2, "Initiating shutdown of queue %d ('%s').", q->qid, q->name); queue_shutdown(q); } ll_finish(sysdata->queues); // if we have controllers that are attempting to connect, we need to change their status so that they dont. logger(sysdata->logging, 2, "Stopping controllers that are connecting."); ll_start(sysdata->controllers); while ((ct = ll_next(sysdata->controllers))) { BIT_SET(ct->flags, FLAG_CONTROLLER_FAILED); if (ct->connect_event) { event_free(ct->connect_event); ct->connect_event = NULL; } } ll_finish(sysdata->controllers); // Put stats event on notice that we are shutting down, so that as soon as there are no more nodes, it needs to stop its event. assert(sysdata != NULL); assert(sysdata->stats != NULL); stats = sysdata->stats; assert(stats->shutdown == 0); stats->shutdown ++; // Tell the logging system not to use events anymore. log_direct(sysdata->logging); }