Пример #1
0
tibrv_status
send_snap(char *subject)
{
    tibrv_status        err = TIBRV_OK;
    char                snap_name[TIBRV_SUBJECT_MAX];
    char                reply_name[TIBRV_SUBJECT_MAX];

    /* Reuse our message */
    tibrvMsg_Reset(msg);

    /* Create the _SNAP name */
    sprintf(snap_name, "_SNAP.%s", subject);

    err = tibrvMsg_SetSendSubject(msg, snap_name);

    if (err != TIBRV_OK)
    {
        fprintf(stderr, "%s: Failed to set send name: %s --%s\n",
                    progname, snap_name, tibrvStatus_GetText(err));
    }
    else
    {
        /* Get our replyname */
        create_replyname(reply_name, subject);

        err = tibrvMsg_SetReplySubject(msg, reply_name);

        if (err != TIBRV_OK)
        {
            fprintf(stderr, "%s: Failed to set reply name: %s --%s\n",
                    progname, reply_name, tibrvStatus_GetText(err));
        }
    }


    if (err == TIBRV_OK)
    {
        /* Send the _SNAP message */
        err = tibrvTransport_Send(transport, msg);
        if (err != TIBRV_OK)
        {
            fprintf(stderr, "%s: Failed to send message --%s\n",
                    progname, tibrvStatus_GetText(err));
        }
    }

    return(err);
}
Пример #2
0
//	////////////////////////////////////////////////////////////////////////////
std::string RvExceptionStatus::GetStatusString(tibrv_status rv_status,
	const char *other_text)
{
	std::ostringstream status_string;

	status_string << "TibCo/Rendezvous exception resulted from status " <<
		"code = " << rv_status << ", status text = '" <<
		tibrvStatus_GetText(rv_status) << "'" <<
		((other_text != NULL) ? ": " : "") <<
		((other_text != NULL) ? other_text : "");

	return(status_string.str());
}
Пример #3
0
void listen_callback (
    tibrvEvent          event,
    tibrvMsg            message,
    void*               closure)
{
    tibrv_status err = TIBRV_OK;
    const char* send_subject;

    err = tibrvMsg_GetSendSubject(message, &send_subject);

    if (err != TIBRV_OK)
    {
        fprintf(stderr,
                "%s: Failed to get send subject in listen callback --%s\n",
                progname, tibrvStatus_GetText(err));
    }
    else
    {
        /* Call routine to send snap message */
        send_snap((char *)send_subject);
    }
}
Пример #4
0
int
main(int argc, char **argv)
{
    int                 currentArg;
    tibrv_status        err = TIBRV_OK;
    tibrvEvent          snapId = TIBRV_INVALID_ID;
    tibrvEvent          listenId = TIBRV_INVALID_ID;
    char                reply_name[TIBRV_SUBJECT_MAX];

    char                *serviceStr=NULL;
    char                *networkStr=NULL;
    char                *daemonStr=NULL;

    progname = argv[0];

    /*
     * Parse arguments for possible optional parameter pairs.
     * These must precede the subject(s).
     */
    currentArg = get_InitParms( argc, argv, 2,
                                &serviceStr, &networkStr, &daemonStr );

    /*
     * Create internal TIB/Rendezvous machinery
     */

    err = tibrv_Open();
    if(err != TIBRV_OK)
    {
        fprintf(stderr, "%s: Failed to open TIB/Rendezvous --%s\n",
                progname, tibrvStatus_GetText(err));
        exit(1);
    }

    /*
     * Initialize the transport with the given parameters or default NULLs.
     */

    err = tibrvTransport_Create(&transport, serviceStr,
                                networkStr, daemonStr);
    if (err != TIBRV_OK)
    {
        fprintf(stderr, "%s: Failed to initialize transport --%s\n",
                progname, tibrvStatus_GetText(err));
        exit(1);
    }

    tibrvTransport_SetDescription(transport, progname);

    /* Create the message we'll use many times */
    err = tibrvMsg_Create(&msg);

    if (err != TIBRV_OK)
    {
        fprintf(stderr, "%s: Failed to create message --%s\n",
                progname, tibrvStatus_GetText(err));
        exit(1);
    }


    /*
     * Step through command line, getting subjects
     */

    while (currentArg < argc)
    {
        printf("Publishing: subject=\"%s\"\n", argv[currentArg]);

        /*
         * Create listener for the same subject name that
         * rvcache is listening upon.
         */
        err = tibrvEvent_CreateListener(&listenId,
                                        TIBRV_DEFAULT_QUEUE,
                                        listen_callback,
                                        transport,
                                        argv[currentArg],
                                        NULL);

        if (err != TIBRV_OK)
        {
            fprintf(stderr,
                    "%s: Failed to create listener for subject: %s --%s\n",
                    progname, argv[currentArg], tibrvStatus_GetText(err));
            exit(1);
        }

        create_replyname(reply_name, argv[currentArg]);

        /* Create the listener for snapped message */
        err = tibrvEvent_CreateListener(&snapId,
                                        TIBRV_DEFAULT_QUEUE,
                                        snap_callback,
                                        transport,
                                        reply_name,
                                        NULL);

        if (err != TIBRV_OK)
        {
            fprintf(stderr,
                    "%s: Failed to create listener for snap reply: %s --%s\n",
                    progname, reply_name, tibrvStatus_GetText(err));
            exit(1);
        }

        /* Call routine to send snap message */
        err = send_snap(argv[currentArg]);


        if (err != TIBRV_OK)
        {
            fprintf(stderr, "%s: %s in sending \"%s\"\n",
                    progname, tibrvStatus_GetText(err), argv[currentArg]);
            exit(1);
        }

        currentArg++;
    }

    /*
     * Dispatch loop - dispatches events which have been
     * placed on the event queue
     */

    while (tibrvQueue_Dispatch(TIBRV_DEFAULT_QUEUE) == TIBRV_OK);

    /*
     * Shouldn't get here.....
     */

    tibrvMsg_Destroy(msg);
    tibrvEvent_Destroy(listenId);
    tibrvEvent_Destroy(snapId);

    tibrv_Close();

    return 0;

}
Пример #5
0
int
main(int argc, char **argv)
{
    tibrv_status        err;

    int                 i=1;

    char                *serviceStr = NULL;
    char                *networkStr = NULL;
    char                *daemonStr = NULL;
    struct stfdata      data;   /* use for closure data block */

    tibrv_f64 timeInt = 10;     /* publish time every 10 seconds */

    char                *ftserviceStr = NULL;
    char                *ftnetworkStr = NULL;
    char                *ftdaemonStr = NULL;
    char *              groupName = "TIBRVFT_TIME_EXAMPLE";
    tibrv_u16           ftweight=50;
    tibrv_u16           numactive=1;
    tibrv_f64           hbInterval=1.5;
    tibrv_f64           prepareInterval=0;
    tibrv_f64           activateInterval=4.8;

    tibrvEvent          advId;

    /*
     * Warn user - RVFT initialization takes one activation interval.
     */

    progname = argv[0];

    fprintf( stdout, "%s initializing...\n", progname);

    i= get_InitParms( argc, argv, 0,
                      &serviceStr, &networkStr, &daemonStr,
                      &ftserviceStr, &ftnetworkStr, &ftdaemonStr, &ftweight);


    if (argc > i)
    {
        ftweight = (tibrv_u16) atol(argv[i++]);
    }


    /* Create internal TIB/Rendezvous machinery */
    err = tibrv_Open();

    if (err != TIBRV_OK)
    {
        fprintf(stderr, "%s: Failed to open TIB/RV --%s\n",
                progname, tibrvStatus_GetText(err));
        exit(1);
    }


    /*
     * Main Transport is for timestamp publishing.
     * Initialize it with the given parameters or default NULLs.
     */

    err = tibrvTransport_Create(&data.transport, serviceStr,
                                networkStr, daemonStr);
    if (err != TIBRV_OK)
    {
        fprintf(stderr, "%s: Failed to initialize main transport --%s\n",
                progname, tibrvStatus_GetText(err));
        exit(2);
    }


    /* Prepare for publishing timestamp every 10 seconds.
     * Start repeating timer here.  Check a flag in the timer
     * callback routine, pubTime, as to whether this member is
     * the active group member.  If so it will format and send
     * the timestamp message.
     */

    fprintf(stdout,
     "Active group member will publish time every 10 seconds.\n");
    fprintf(stdout, "Subject is %s\n", SUBJECT);
    fprintf(stdout, "Inactive will not publish time\n");

    err = tibrvEvent_CreateTimer(
                &data.timerId,
                TIBRV_DEFAULT_QUEUE,
                pubTime,
                timeInt,
                &data);

    if(err != TIBRV_OK)
    {
        fprintf(stderr, "Error adding repeating timer: --%s\n",
                tibrvStatus_GetText(err));
        exit(3);
    }


    /* RVFT communications may benefit from a separate transport. */

    err = tibrvTransport_Create(&data.fttransport, ftserviceStr,
                                ftnetworkStr, ftdaemonStr);
    if (err != TIBRV_OK)
    {
        fprintf(stderr,
                "%s: Failed to initialize fault tolerant transport --%s\n",
                progname, tibrvStatus_GetText(err));
        exit(3);
    }

    /* Join the RVFT group. */

    err = tibrvftMember_Create(&data.groupId,
                                TIBRV_DEFAULT_QUEUE,
                                processInstruction,
                                data.fttransport,
                                groupName,
                                ftweight,
                                numactive,
                                hbInterval,
                                prepareInterval,
                                activateInterval,
                                &data); /* carry our data to others */

    if (err != TIBRV_OK)
    {
        fprintf(stderr,"%s: Failed to join group - %s\n", progname,
                tibrvStatus_GetText(err));
        exit(4);
    }

    /*
     * Subscribe to RVFT advisories.
     */

    err = tibrvEvent_CreateListener(
                &advId,
                TIBRV_DEFAULT_QUEUE,
                advCB,
                data.fttransport,
                "_RV.*.RVFT.*.TIBRVFT_TIME_EXAMPLE",
                &data);

    if(err != TIBRV_OK)
    {
        fprintf(stderr,"%s: Failed to start listening to advisories - %s\n",
                progname, tibrvStatus_GetText(err));
        exit(5);
    }


    /*
     * Dispatch loop - dispatches events which have been placed on the event queue
     */

    while (tibrvQueue_Dispatch(TIBRV_DEFAULT_QUEUE) == TIBRV_OK)
    {
        /* over and over again */
    }

    /*
     * Shouldn't get here.....
     */

    tibrvEvent_Destroy(advId);
    tibrvEvent_Destroy(data.timerId);
    tibrvftMember_Destroy(data.groupId);

    tibrv_Close();

    exit(0);
}
Пример #6
0
int
main(int argc, char **argv)
{
    tibrv_status        err;
    tibrvTransport      transport;
    tibrvMsg            message;

    int                 currentArg;
    int                 subjectLocation;

    char*               serviceStr = NULL;
    char*               networkStr = NULL;
    char*               daemonStr  = NULL;

    char*               progname = argv[0];

    /*
     * Parse arguments for possible optional parameter pairs.
     * These must precede the subject and message strings.
     */
    currentArg = get_InitParms(argc, argv, MIN_PARMS, &serviceStr,
                               &networkStr, &daemonStr );

    /*
     * Create internal TIB/Rendezvous machinery
     */
    err = tibrv_Open();
    if (err != TIBRV_OK)
    {
        fprintf(stderr, "%s: Failed to open TIB/RV: %s\n",
                progname, tibrvStatus_GetText(err));
        exit(1);
    }


    /*
     * Initialize the transport with the given parameters or default NULLs.
     */

    err = tibrvTransport_Create(&transport, serviceStr,
                                networkStr, daemonStr);
    if (err != TIBRV_OK)
    {
        fprintf(stderr, "%s: Failed to initialize transport: %s\n",
                progname, tibrvStatus_GetText(err));
        exit(1);
    }

    tibrvTransport_SetDescription(transport, progname);

    /*
     * Create message
     */
    err = tibrvMsg_Create(&message);
    if (err != TIBRV_OK)
    {
        fprintf(stderr, "%s: Failed to create message: %s\n",
                progname, tibrvStatus_GetText(err));
        exit(1);
    }


    /*
     * Step through command line, getting first the subject,
     * then publishing each message on that subject.
     */

    subjectLocation = currentArg++;

    while(currentArg < argc)
    {
        printf("Publishing: subject=%s \"%s\"\n",
                argv[subjectLocation], argv[currentArg]);

        /* Update the string in our message */
        err = tibrvMsg_UpdateString(message, FIELD_NAME, argv[currentArg]);

        if (err == TIBRV_OK)
        {
            /* Set the subject name */
            err = tibrvMsg_SetSendSubject(message, argv[subjectLocation]);

            if (err == TIBRV_OK)
            {
                err = tibrvTransport_Send(transport, message);
            }
        }

        if ( err != TIBRV_OK)
        {
            fprintf(stderr, "%s: %s in sending \"%s\" to \"%s\"\n",
                    progname, tibrvStatus_GetText(err),
                    argv[currentArg], argv[subjectLocation]);
            break;
        }

        currentArg++;
    }

    /*
     * Destroy message
     */
    tibrvMsg_Destroy(message);

    /*
     * tibrv_Close() will destroy the transport and guarantee delivery.
     */

    tibrv_Close();

    exit(0);
}
Пример #7
0
static void
pubTime(tibrvEvent      event,
        tibrvMsg        message,
        void *          closure)
{
    tibrv_status        err;
    time_t              curtime;
    tibrvMsgDateTime    tib_time;
    tibrvMsg            time_message;

    struct stfdata * datap = (struct stfdata *) closure;

    if (!datap->active)         /* do nothing if not active */
        return;

    /* Initialize tib_time variables */
    tib_time.nsec = 0;
    tib_time.sec = 0;

    time( &curtime);

    /* Set our seconds value */
    tib_time.sec = (tibrv_i64)curtime;

    /*
     * Create message
     */
    err = tibrvMsg_Create(&time_message);
    if (err != TIBRV_OK)
    {
        fprintf(stderr, "%s: Failed to create message --%s\n",
                progname, tibrvStatus_GetText(err));
    }
    else
    {
        /* Add the time to the message */
        err = tibrvMsg_AddDateTime(
                time_message,
                "DATA",
                &tib_time);

        if(err != TIBRV_OK)
        {
            fprintf(stderr, "Error generating timestamp data: %s\n",
                        tibrvStatus_GetText(err));
        }
        else
        {
            err = tibrvMsg_SetSendSubject(time_message, SUBJECT);
            if(err != TIBRV_OK)
            {
                fprintf(stderr, "Error setting send subject: %s\n",
                        tibrvStatus_GetText(err));
            }
            else
            {
                err = tibrvTransport_Send(datap->transport, time_message);

                if(err != TIBRV_OK)
                {
                    fprintf(stderr, "Error publishing timestamp message: %s\n",
                                tibrvStatus_GetText(err));
                }
            }
        }
        tibrvMsg_Destroy(time_message);
    }
    return;
}
Пример #8
0
/* This is the main routine. */
int
main(int argc, char** argv)
{
    int                 last_argument_index;

    tibrv_status        return_code;

    char*               serviceStr = DEFAULT_SERVICE;
    char*               networkStr = DEFAULT_NETWORK;
    char*               daemonStr  = DEFAULT_DAEMON;

    tibrvMsg            search_request;
    tibrvMsg            search_reply;

    const char*         server_subject;
    static char         request_subject[TIBRV_SUBJECT_MAX];
    static char         response_subject[TIBRV_SUBJECT_MAX];

    tibrvMsg            client_request;

    tibrvMsgDateTime    date_time_start, date_time_stop;
    tibrv_f64           time_start, time_stop, elapsed;

    tibrv_u32           i;

    /* Parse the command line. */
    last_argument_index = getParameters(argc, argv,
                                        &serviceStr, &networkStr, &daemonStr);
    if (last_argument_index < argc) {
        requests = atoi(argv[last_argument_index]);
    }

    /* The TIB/Rendezvous machinery needs to be started. */
    return_code = tibrv_Open();
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s failed to open the TIB/Rendezvous machinery: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    /* A transport needs to be created. */
    return_code = tibrvTransport_Create(&transport,
                                        serviceStr, networkStr, daemonStr);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s failed to create a transport: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }
    tibrvTransport_SetDescription(transport, program_name);

    /* We create the message we will send in order to locate a server. */
    return_code = tibrvMsg_Create(&search_request);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s failed to create a search request: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    /* Set the send subject to locate our server. */
    return_code = tibrvMsg_SetSendSubject(search_request,
                                          SEARCH_SUBJECT);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s failed to set the send subject of a search request: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    fprintf(stdout,
            "%s is searching for a server on subject %s...\n",
            program_name, SEARCH_SUBJECT);

    /* Send a request message to locate a server and receive its reply.
       SendRequest is a synchronous call which uses a private queue to
       receive its reply.  No external dispatching mechanism is involved. */

    return_code = tibrvTransport_SendRequest(transport,
                                             search_request,
                                             &search_reply,
                                             SEARCH_TIMEOUT);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s failed to locate a server: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    /*
      The search reply we receive from a server should contain a reply
      subject we can use to send requests to that server.
    */

    return_code = tibrvMsg_GetReplySubject(search_reply,
                       &server_subject);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s failed to get the request subject of a search reply: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }
    strcpy(request_subject, server_subject);

    fprintf(stdout,
            "%s successfully located a server: %s\n",
            program_name, request_subject);

    /* Destroy the server's reply message to reclaim memory. */
    return_code = tibrvMsg_Destroy(search_reply);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s failed to destroy a reply to a client request: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    /*
      Create response queue, an inbox point-to-point subject, and a listener
      using that subject for responses from the server to a series of
      messages.
    */

    tibrvQueue_Create(&response_queue);
    tibrvTransport_CreateInbox(transport, response_subject, TIBRV_SUBJECT_MAX);
    return_code = tibrvEvent_CreateListener(&response_id,
                                            response_queue,
                                            serverResponse,
                                            transport,
                                            response_subject,
                                            NULL);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr, "%s failed to initialize response mechanism: %s\n",
                program_name, tibrvStatus_GetText(return_code));
        exit(1);
    }

    /* Start a dispatcher thread to dispatch response messages. */
    return_code = tibrvDispatcher_CreateEx(&response_thread,
                                           response_queue,
                                           REQUEST_TIMEOUT);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr, "failed to create response dispatcher--%s\n",
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    /* Because this is only a test, we will repeatedly send the same request
       message to the server.  We'll change the data in the message each time.
    */

    return_code = tibrvMsg_Create(&client_request);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s failed to create a client request: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    /* Set the send subject to the server's (inbox) subject. */
    return_code = tibrvMsg_SetSendSubject(client_request,
                                          request_subject);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s failed to set the send subject of a client request: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    /* Set the reply subject to our inbox subject, allowing a point-to-point
       reply from our server.  We won't use SendRequest, so we won't block
       waiting for th reply. */

    return_code = tibrvMsg_SetReplySubject(client_request,
                                           response_subject);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s failed to set the reply subject of a client request: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    fprintf(stdout, "Starting test...\n");

    /* We will time this test. */
    tibrvMsg_GetCurrentTime(&date_time_start);
    time_start = date_time_start.sec + (date_time_start.nsec / 1000000000.0);

    for (i = 0; i < requests; i++)
    {
        /* Put some data into the message to the server. */
        return_code = tibrvMsg_UpdateU32(client_request, "x",
                     ((tibrv_u32) rand()));
        if (return_code != TIBRV_OK)
        {
            fprintf(stderr,
                    "%s failed to update a client request: %s\n",
                    program_name,
                    tibrvStatus_GetText(return_code));
            exit(1);
        }

        return_code = tibrvMsg_UpdateU32(client_request, "y",
                     ((tibrv_u32) rand()));
        if (return_code != TIBRV_OK)
        {
            fprintf(stderr,
                    "%s failed to update a client request: %s\n",
                    program_name,
                    tibrvStatus_GetText(return_code));
            exit(1);
        }

        /* Send a request message to the server. */
        return_code = tibrvTransport_Send(transport,
                                          client_request);
        if (return_code != TIBRV_OK)
        {
            fprintf(stderr,
                    "%s failed to send a client request: %s\n",
                    program_name,
                    tibrvStatus_GetText(return_code));
            exit(1);
        }

    }

    /* Report the number of messages sent and number received while sending. */
    fprintf(stdout,
        "%d request messages sent.  %d messages received while sending.\n",
            requests, responses);

    tibrvDispatcher_Destroy(response_thread);

    /* Dispatch loop - dispatches events from the event queue in the main thread,
       in addition to the dispatcher thread created earlier.  Note that if the
       last message is dispatched from that thread while this loop is executing
       its TimedDispatch call, the loop will exit only after it times out.  The
       total time will be the time required to receive all the replies plus the
       REQUEST_TIMEOUT value.  */

    while ((responses < requests) &&
           (tibrvQueue_TimedDispatch(response_queue, REQUEST_TIMEOUT) ==
                    TIBRV_OK));

    /* Report the run statistics for this test. */
    tibrvMsg_GetCurrentTime(&date_time_stop);
    time_stop = date_time_stop.sec + (date_time_stop.nsec / 1000000000.0);

    elapsed = time_stop - time_start;

    if (responses >= requests)
    {
        fprintf(stdout, "%s received all %d server replies\n",
                program_name, responses);
        fprintf(stdout, "%d requests took %.2f secs to process.\n",
                requests, elapsed);
        fprintf(stdout,
                "This result implies an effective rate of %.1f requests/second.\n",
                ((tibrv_f64) requests / elapsed));
        exit_status = 0;
    }
    else
    {
        fprintf(stdout, "Received %d responses to  %d requests.\n",
                responses, requests);
        exit_status = 1;
    }


    /* Destroy our listener event and dispatcher thread. */
    tibrvEvent_Destroy(response_id);
    tibrvDispatcher_Destroy(response_thread);

    /* Destroy our queue. */
    tibrvQueue_Destroy(response_queue);

    /* Destroy our transport. */
    tibrvTransport_Destroy(transport);

    /* Close the Tibrv machinery and exit. */
    tibrv_Close();

    exit(exit_status);
}
Пример #9
0
/* This is the main routine. */
int
main(int    argc,
     char** argv)
{
    tibrv_status        return_code;

    tibrvEvent          request_event = 0;

    char*               serviceStr = DEFAULT_SERVICE;
    char*               networkStr = DEFAULT_NETWORK;
    char*               daemonStr  = DEFAULT_DAEMON;

    char                disp_name[255]; /* string buffer */

    int                 i, vcthreads=0;

    serverRec*          myServer;


    /* Parse the command line and set up the transport parameters. */
    getParameters(argc, argv, &serviceStr, &networkStr, &daemonStr, &vcthreads);

    /* The TIB/Rendezvous machinery needs to be started. */
    return_code = tibrv_Open();
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s failed to open the TIB/Rendezvous machinery: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    /* Each 'server' manages multiple virtual circuits.  We create
    a server structure to do the bookkeeping.  A more trivial example
    could just handle one VC at a time. */

    myServer = (serverRec*)malloc(sizeof(serverRec));

    /* A network transport needs to be created. We listen for search
    requests on this transport. */
    return_code = tibrvTransport_Create(&myServer->server_transport,
                                        serviceStr, networkStr, daemonStr);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s: failed to create a transport: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }
    tibrvTransport_SetDescription(myServer->server_transport, program_name);

    /* This listener will pay attention to VC server searches. */
    return_code = tibrvEvent_CreateListener(&myServer->search_event,
                                            TIBRV_DEFAULT_QUEUE,
                                            searchCallback,
                                            myServer->server_transport,
                                            SEARCH_SUBJECT,
                                            (void*)myServer);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s: failed to create a server search listener: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }


    /*  Since we wish to create a unique identifier for this
        server we will create an _INBOX.  An _INBOX is unique
        not only on this host, but in the entire TIB domain in
        which it is running.  If we want to extend this server
        to receive commands on this _INBOX in the future it is
        trivial to do so.

        We will store this as our server_subject and send it
        as our reply_subject in all control or protocol messages.
    */

    tibrvTransport_CreateInbox(myServer->server_transport,
                               myServer->server_inbox,
                               TIBRV_SUBJECT_MAX);

    return_code = tibrvEvent_CreateListener(&myServer->server_inbox_event,
                                            TIBRV_DEFAULT_QUEUE,
                                            serverControlInboxCallback,
                                            myServer->server_transport,
                                            myServer->server_inbox,
                                            (void*)myServer);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s: failed to create a client request listener: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    /* Now a queue group to hold the queues for the VCs that we
    have open */

    return_code = tibrvQueueGroup_Create(&myServer->vc_queues);
    if (return_code != TIBRV_OK) {
        fprintf(stderr,
                "%s: failed to create queue group for VCs: %s\n",
                program_name, tibrvStatus_GetText(return_code));
    }

    /* Finally, thread(s) dispatching off of the queue group.  We
    can have a number of threads waiting on this one queue group
    that will service all of the VC(s) and their individual
    queues */

    if (vcthreads>VC_THREAD_MAX) {
        vcthreads = VC_THREAD_MAX;
        fprintf(stderr,
                "%s: Maximum threads is %d - using %d\n",
                program_name, VC_THREAD_MAX, VC_THREAD_MAX);
    }

    else if (vcthreads <= 0) vcthreads = 1; /* need at least one */

    for (i=0;i<vcthreads;i++) {
        return_code = tibrvDispatcher_Create(
            &myServer->vc_dispatchers[i],
            myServer->vc_queues);

        if (return_code != TIBRV_OK)
        {
            fprintf(stderr,
                    "%s: failed to create dispatcher thread: %s\n", program_name,
                    tibrvStatus_GetText(return_code));
        }
        sprintf(disp_name, "%s_%d", myServer->server_name, i);
        return_code = tibrvDispatcher_SetName(
            myServer->vc_dispatchers[i],
            disp_name);
    }


    /* Display a server-ready message. */
    fprintf(stderr, "Listening for client requests on subject %s.\n"
            "Wait time is %.0f secs.\n%s ready...\n",
            SEARCH_SUBJECT, SERVER_TIMEOUT, program_name);


    /* If this server remains idle for more than the timeout value, exit. */
    while (tibrvQueue_TimedDispatch(TIBRV_DEFAULT_QUEUE, SERVER_TIMEOUT) == TIBRV_OK);

    /* Destroy our Tibrv objects and close the Tibrv machinery. */
    tibrvEvent_Destroy(myServer->search_event);
    tibrvEvent_Destroy(request_event);
    tibrvTransport_Destroy(myServer->server_transport);
    free(myServer);
    tibrv_Close();

    exit(0);
}
Пример #10
0
static void
searchCallback(tibrvEvent event,
               tibrvMsg   message,
               void*      closure)
{
    vcRec*      vc = NULL;
    serverRec*  server = (serverRec*)closure;
    tibrvMsg    search_reply;

    tibrv_status return_code = TIBRV_OK;

    /* We define the message we will use to reply to server searches. */

    return_code = tibrvMsg_Create(&search_reply);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s: failed to create a reply to a server search: %s\n",
                "searchCallback",
                tibrvStatus_GetText(return_code));
        exit(1);
    }


    /* Set the required reply subject as the unique id of our server.
       This is also our control inbox. */

    return_code = tibrvMsg_SetReplySubject(search_reply,
                        server->server_inbox);

    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s: failed to set reply subject for a search reply: %s\n",
                "searchCallback",
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    /* Call our routine to accept the virtual circuit received from a
     * client. */
    return_code = createVC(server, &vc);

    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s: failed to create VC: %s\n",
                "searchCallback",
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    /* Register the listener on the VC event queue and add the
    vc_queue event queue to the queue group that the server is
    dispatching. */

    return_code = tibrvEvent_CreateListener(&vc->vc_msg_event,
                                            vc->vc_queue,
                                            requestCallback,
                                            vc->vc_transport,
                                            WORK_SUBJECT,
                                            (void*)vc);

    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s: failed to set WORK_SUBJECT callback: %s\n",
                "createVC",
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    tibrvQueueGroup_Add(server->vc_queues,
                vc->vc_queue);


    /* Add the subjects as data to the message and send it. */
    return_code = tibrvMsg_AddString(search_reply,
                        "connect_subject",
                        vc->connect_subject);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s: failed to set VC connect_subject for a server search reply: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    return_code = tibrvMsg_AddString(search_reply,
                        "request_subject",
                        WORK_SUBJECT);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s failed to set VC request_subject for a server search reply: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }


    return_code = tibrvTransport_SendReply(server->server_transport, search_reply,
                                        message);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s failed to send a reply to a VC server search: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }


    vc->vc_state = waiting;

    /* Wait for the connection.  The timeout is how long we have to complete
    the handshake with our correspondent */
    return_code = tibrvTransport_WaitForVcConnection(vc->vc_transport,
                                VC_ACCEPT_TIMEOUT);

    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s failed on WaitForVcConnection in VC server search: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
    }

    fprintf(stderr,"%s VC accepted and connected\n", program_name);

    return_code = tibrvMsg_Destroy(search_reply);

    vc->vc_state = connected;

    fprintf(stderr,
            "%s: VCs active: %d\n",
            program_name, ++vc->server->vc_count);

}
Пример #11
0
tibrv_status
createVC(serverRec* server,
         vcRec**    vc)
{
    tibrv_status    return_code = TIBRV_OK;
    vcRec*          newVc = NULL;

    /* Since we want to receive virtual circuit connections, we need
       to create a virtual circuit transport to act as an acceptor. */

    newVc = (vcRec*)malloc(sizeof(vcRec));

    newVc->vc_state = initializing;
    newVc->msgs_in = 0;
    newVc->msgs_out = 0;
    newVc->server = server;

    return_code = tibrvTransport_CreateAcceptVc(
            &newVc->vc_transport,
            &newVc->connect_subject,
            server->server_transport);

    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s: failed to create AcceptVc: %s\n",
                "createVC",
                tibrvStatus_GetText(return_code));
        free(newVc);
        return(return_code);
    }

    /* Register disconnect callback to unwind all of this work.
    We receive the event on the VC transport, but we process it
    using the server master thread processing on the DEFAULT
    queue */

    return_code = tibrvEvent_CreateListener(&newVc->vc_disconnect_event,
                                            TIBRV_DEFAULT_QUEUE,
                                            disconnectedVcCallback,
                                            newVc->vc_transport,
                                            DISCONNECT_ADVISORY,
                                            (void*)newVc);

    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s: failed to set the DISCONNECT_ADVISORY callback: %s\n",
                "createVC",
                tibrvStatus_GetText(return_code));
        tibrvTransport_Destroy(newVc->vc_transport);
        free(newVc);
        return(return_code);
    }

    /* create the incoming event queue */
    return_code = tibrvQueue_Create(&newVc->vc_queue);
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s: failed to create vc_queue event queue: %s\n",
                "createVC",
                tibrvStatus_GetText(return_code));
        tibrvEvent_Destroy(newVc->vc_disconnect_event);
        tibrvTransport_Destroy(newVc->vc_transport);
        free(newVc);
        return(return_code);
    }

    /* Creeate an inbox subject on our vc for requests.  This could
     * also be a broadcast subject.  The server/client communication
     * will still be point-to-point over a virtual circuit.  Create
     * a listener on this subject. */
    tibrvTransport_CreateInbox(newVc->vc_transport,
                               newVc->vc_inbox,
                               TIBRV_SUBJECT_MAX);

    return_code = tibrvEvent_CreateListener(&newVc->vc_inbox_event,
                                            newVc->vc_queue,
                                            vcControlInboxCallback,
                                            newVc->vc_transport,
                                            newVc->vc_inbox,
                                            (void*)newVc);

    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s: failed to set vc_control_inbox callback: %s\n",
                "createVC",
                tibrvStatus_GetText(return_code));
        tibrvQueue_Destroy(newVc->vc_queue);
        tibrvEvent_Destroy(newVc->vc_disconnect_event);
        tibrvTransport_Destroy(newVc->vc_transport);
        free(newVc);
        return(return_code);
    }

    *vc = newVc;
    return(return_code);
}
Пример #12
0
static void
requestCallback(tibrvEvent event,
                tibrvMsg   message,
                void*      closure)
{
    tibrv_status    return_code = TIBRV_OK;
    tibrvMsg        request_reply;
    tibrv_u32       x, y, sum;
    vcRec*          vc = (vcRec*)closure;

    vc->msgs_in++;

    /* Get the values in field "x" */
    return_code = tibrvMsg_GetU32(message, "x", &x);;
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s failed to get the value of x: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    /* Get the values in field "y" */
    return_code = tibrvMsg_GetU32(message, "y", &y);;
    if (return_code != TIBRV_OK)
    {
        fprintf(stderr,
                "%s failed to get the value of y: %s\n",
                program_name,
                tibrvStatus_GetText(return_code));
        exit(1);
    }

    /* Add the values and update the reply message with the sum. */
    sum = x + y;


    if (new_msg)
    {
        /* Create a new reply message. */
        return_code = tibrvMsg_Create(&request_reply);
        if (return_code != TIBRV_OK)
        {
            fprintf(stderr,
                    "%s failed to initialize a reply to a client request: %s\n",
                    program_name,
                    tibrvStatus_GetText(return_code));
            exit(1);
        }

        /* Put the sum in the reply message. */
        return_code = tibrvMsg_UpdateU32(request_reply, "sum", sum);
        if (return_code != TIBRV_OK)
        {
            fprintf(stderr,
                    "%s failed to update a reply to a client request: %s\n",
                    program_name,
                    tibrvStatus_GetText(return_code));
            exit(1);
        }

        /* Send a reply to the request message on the VC transport.

        Note that this either may be a multicast subject or an
        INBOX subject, we do not care which it is. The response will
        go back point to point to the requesting process on the VC
        regardless. */

        return_code = tibrvTransport_SendReply(vc->vc_transport,
                            request_reply, message);
        if (return_code != TIBRV_OK)
        {
            fprintf(stderr,
                    "%s failed to send a reply to a client request: %s\n",
                    program_name,
                    tibrvStatus_GetText(return_code));
            exit(1);
        }

        vc->msgs_out++;

        /* Destroy our reply message to reclaim space. */
        return_code = tibrvMsg_Destroy(request_reply);
        if (return_code != TIBRV_OK)
        {
            fprintf(stderr,
                    "%s failed to destroy a reply to a client request: %s\n",
                    program_name,
                    tibrvStatus_GetText(return_code));
            exit(1);
        }
    }
    else
    {
        /* Put the sum in the request message received from the client. */
        return_code = tibrvMsg_UpdateU32(message, "sum", sum);
        if (return_code != TIBRV_OK)
        {
            fprintf(stderr,
                    "%s failed to update a reply to a client request: %s\n",
                    program_name,
                    tibrvStatus_GetText(return_code));
            exit(1);
        }

        /* Send the message back as a reply to the request message. */
        return_code = tibrvTransport_SendReply(vc->vc_transport,
                                message, message);
        if (return_code != TIBRV_OK)
        {
            fprintf(stderr,
                    "%s failed to send a reply to a client request: %s\n",
                    program_name,
                    tibrvStatus_GetText(return_code));
            exit(1);
        }

        vc->msgs_out++;
    }

}