int main(int argc, char** argv) { Options_t opts; Statistics_t stats; parse_options( argc, argv, &opts ); pn_reactor_t *reactor = pn_reactor(); // set up default handlers for our reactor pn_handler_t *root = pn_reactor_get_handler(reactor); pn_handler_t *lh = listener_handler(&opts, &stats); pn_handler_add(root, lh); pn_handshaker_t *handshaker = pn_handshaker(); pn_handler_add(root, handshaker); // Omit decrefs else segfault. Not sure why they are necessary // to keep valgrind happy for the connection_handler, but not here. // pn_decref(handshaker); // pn_decref(lh); pn_reactor_run(reactor); pn_reactor_free(reactor); addresses_free( &opts.subscriptions ); return 0; }
void listener_dispatch(pn_handler_t *h, pn_event_t *event, pn_event_type_t type) { global_context_t *gc = global_context(h); if (type == PN_REACTOR_QUIESCED) gc->quiesce_count++; else gc->quiesce_count = 0; switch (type) { case PN_CONNECTION_INIT: { pn_connection_t *connection = pn_event_connection(event); // New incoming connection on listener socket. Give each a separate handler. pn_handler_t *ch = connection_handler(gc); pn_handshaker_t *handshaker = pn_handshaker(); pn_handler_add(ch, handshaker); pn_decref(handshaker); pn_record_t *record = pn_connection_attachments(connection); pn_record_set_handler(record, ch); pn_decref(ch); } break; case PN_REACTOR_QUIESCED: { // Two quiesce in a row means we have been idle for a timout period if (gc->opts->timeout != -1 && gc->quiesce_count > 1) global_shutdown(gc); } break; case PN_REACTOR_INIT: { pn_reactor_t *reactor = pn_event_reactor(event); start_listener(gc, reactor); // hack to let test scripts know when the receivers are ready (so // that the senders may be started) if (gc->opts->ready_text) { fprintf(stdout, "%s\n", gc->opts->ready_text); fflush(stdout); } if (gc->opts->timeout != -1) pn_reactor_set_timeout(pn_event_reactor(event), gc->opts->timeout); } break; case PN_REACTOR_FINAL: { if (gc->received == 0) statistics_start(gc->stats); statistics_report(gc->stats, gc->sent, gc->received); } break; default: break; } }
void listener_dispatch ( pn_handler_t *h, pn_event_t * event, pn_event_type_t type ) { global_context_t * gc = global_context ( h ); if ( type == PN_REACTOR_QUIESCED ) gc->quiesce_count++; else gc->quiesce_count = 0; switch (type) { case PN_CONNECTION_INIT: { pn_connection_t * connection = pn_event_connection ( event ); // New incoming connection on listener socket. Give each a separate handler. pn_handler_t *ch = connection_handler(gc); pn_handshaker_t *handshaker = pn_handshaker(); pn_handler_add(ch, handshaker); pn_decref(handshaker); pn_record_t *record = pn_connection_attachments(connection); pn_record_set_handler(record, ch); pn_decref(ch); } break; case PN_REACTOR_INIT: { pn_reactor_t *reactor = pn_event_reactor(event); start_listener(gc, reactor); } break; case PN_REACTOR_FINAL: { if (gc->received == 0) statistics_start(gc->stats); //statistics_report(gc->stats, gc->sent, gc->received); fclose ( gc->report_fp ); if ( gc->received > 0 ) fprintf ( stderr, "reactor-recv received %d messages.\n", gc->received ); } break; default: break; } }
int main(int argc, char** argv) { Options_t opts; Statistics_t stats; parse_options( argc, argv, &opts ); pn_reactor_t *reactor = pn_reactor(); pn_handler_t *sh = sender_handler(&opts, &stats); pn_handler_add(sh, pn_handshaker()); pn_reactor_connection(reactor, sh); pn_reactor_run(reactor); pn_reactor_free(reactor); pn_handler_free(sh); addresses_free(&opts.targets); return 0; }
// create a new handler for the engine and set up the protocolState static rsRetVal _new_handler(pn_handler_t **handler, pn_reactor_t *reactor, dispatch_t *dispatch, configSettings_t *config, threadIPC_t *ipc) { DEFiRet; *handler = pn_handler_new(dispatch, sizeof(protocolState_t), _del_handler); CHKmalloc(*handler); pn_handler_add(*handler, pn_handshaker()); protocolState_t *pState = PROTOCOL_STATE(*handler); memset(pState, 0, sizeof(protocolState_t)); pState->buffer_size = 64; // will grow if not enough pState->encode_buffer = (char *)malloc(pState->buffer_size); CHKmalloc(pState->encode_buffer); pState->reactor = reactor; pState->stopped = false; // these are _references_, don't free them: pState->config = config; pState->ipc = ipc; finalize_it: RETiRet; }
void sender_dispatch(pn_handler_t *h, pn_event_t *event, pn_event_type_t type) { sender_context_t *sc = sender_context(h); switch (type) { case PN_CONNECTION_INIT: { pn_connection_t *conn = pn_event_connection(event); pn_connection_set_container(conn, pn_string_get(sc->container_id)); pn_connection_set_hostname(conn, pn_string_get(sc->hostname)); pn_connection_open(conn); pn_session_t *ssn = pn_session(conn); pn_session_open(ssn); pn_link_t *snd = pn_sender(ssn, "sender"); const char *path = pn_url_get_path(sc->send_url); if (path && strlen(path)) { pn_terminus_set_address(pn_link_target(snd), path); pn_terminus_set_address(pn_link_source(snd), path); } pn_link_open(snd); } break; case PN_LINK_FLOW: { pn_link_t *snd = pn_event_link(event); while (pn_link_credit(snd) > 0 && sc->sent < sc->opts->msg_count) { if (sc->sent == 0) statistics_start(sc->stats); char tag[8]; void *ptr = &tag; *((uint64_t *) ptr) = sc->sent; pn_delivery_t *dlv = pn_delivery(snd, pn_dtag(tag, 8)); // setup the message to send pn_message_t *msg = sc->message; pn_message_set_address(msg, sc->opts->targets.addresses[0]); sc->id.u.as_ulong = sc->sent; pn_message_set_correlation_id(msg, sc->id); pn_message_set_creation_time(msg, msgr_now()); size_t size = sc->encoded_data_size; int err = pn_message_encode(msg, sc->encoded_data, &size); check(err == 0, "message encoding error"); pn_link_send(snd, sc->encoded_data, size); pn_delivery_settle(dlv); sc->sent++; } if (sc->sent == sc->opts->msg_count && !sc->opts->get_replies) { pn_link_close(snd); pn_connection_t *conn = pn_event_connection(event); pn_connection_close(conn); } } break; case PN_LINK_INIT: { pn_link_t *link = pn_event_link(event); if (pn_link_is_receiver(link)) { // Response messages link. Could manage credit and deliveries in this handler but // a dedicated handler also works. pn_handler_t *replyto = replyto_handler(sc); pn_flowcontroller_t *fc = pn_flowcontroller(1024); pn_handler_add(replyto, fc); pn_decref(fc); pn_handshaker_t *handshaker = pn_handshaker(); pn_handler_add(replyto, handshaker); pn_decref(handshaker); pn_record_t *record = pn_link_attachments(link); pn_record_set_handler(record, replyto); pn_decref(replyto); } } break; case PN_CONNECTION_LOCAL_CLOSE: { statistics_report(sc->stats, sc->sent, sc->received); } break; default: break; } }
int main(int argc, char** argv) { const char *address = "localhost"; const char *msgtext = "Hello World!"; const char *container = "SendExample"; int c; pn_message_t *message = NULL; pn_data_t *body = NULL; pn_reactor_t *reactor = NULL; pn_url_t *url = NULL; pn_connection_t *conn = NULL; /* Create a handler for the connection's events. event_handler() will be * called for each event and delete_handler will be called when the * connection is released. The handler will allocate an app_data_t * instance which can be accessed when the event_handler is called. */ pn_handler_t *handler = pn_handler_new(event_handler, sizeof(app_data_t), delete_handler); /* set up the application data with defaults */ app_data_t *app_data = GET_APP_DATA(handler); memset(app_data, 0, sizeof(app_data_t)); app_data->count = 1; app_data->target = "examples"; /* Attach the pn_handshaker() handler. This handler deals with endpoint * events from the peer so we don't have to. */ { pn_handler_t *handshaker = pn_handshaker(); pn_handler_add(handler, handshaker); pn_decref(handshaker); } /* command line options */ opterr = 0; while((c = getopt(argc, argv, "i:a:c:t:nhq")) != -1) { switch(c) { case 'h': usage(); break; case 'a': address = optarg; break; case 'c': app_data->count = atoi(optarg); if (app_data->count < 1) usage(); break; case 't': app_data->target = optarg; break; case 'n': app_data->anon = 1; break; case 'i': container = optarg; break; case 'q': quiet = 1; break; default: usage(); break; } } if (optind < argc) msgtext = argv[optind]; // create a single message and pre-encode it so we only have to do that // once. All transmits will use the same pre-encoded message simply for // speed. // message = pn_message(); pn_message_set_address(message, app_data->target); body = pn_message_body(message); pn_data_clear(body); // This message's body contains a single string if (pn_data_fill(body, "S", msgtext)) { fprintf(stderr, "Error building message!\n"); exit(1); } pn_data_rewind(body); { // encode the message, expanding the encode buffer as needed // size_t len = 128; char *buf = (char *)malloc(len); int rc = 0; do { rc = pn_message_encode(message, buf, &len); if (rc == PN_OVERFLOW) { free(buf); len *= 2; buf = (char *)malloc(len); } } while (rc == PN_OVERFLOW); app_data->msg_len = len; app_data->msg_data = buf; } pn_decref(message); // message no longer needed reactor = pn_reactor(); url = pn_url_parse(address); if (url == NULL) { fprintf(stderr, "Invalid host address %s\n", address); exit(1); } conn = pn_reactor_connection_to_host(reactor, pn_url_get_host(url), pn_url_get_port(url), handler); pn_decref(url); pn_decref(handler); // the container name should be unique for each client pn_connection_set_container(conn, container); // wait up to 5 seconds for activity before returning from // pn_reactor_process() pn_reactor_set_timeout(reactor, 5000); pn_reactor_start(reactor); while (pn_reactor_process(reactor)) { /* Returns 'true' until the connection is shut down. * pn_reactor_process() will return true at least once every 5 seconds * (due to the timeout). If no timeout was configured, * pn_reactor_process() returns as soon as it finishes processing all * pending I/O and events. Once the connection has closed, * pn_reactor_process() will return false. */ } pn_decref(reactor); return 0; }