RsslRet snapshotSessionConnect(SnapshotSession *pSession, RsslConnectOptions *pOpts, RsslRDMService* service) { RsslError rsslError; pSession->pRsslChannel = rsslConnect(pOpts, &rsslError); if (!pSession->pRsslChannel) { printf("<%s> rsslConnect() failed: %d (%s -- %s)\n\n", pSession->name, rsslError.rsslErrorId, rsslRetCodeToString(rsslError.rsslErrorId), rsslError.text); return rsslError.rsslErrorId; } printf("<%s> Channel connected with FD %d.\n\n", pSession->name, pSession->pRsslChannel->socketId); /* If we need to initialize the channel, make our first call to rsslInitChannel() when * triggered to write. */ if (pSession->pRsslChannel->state == RSSL_CH_STATE_INITIALIZING) pSession->setWriteFd = RSSL_TRUE; else { printf("<%s> Channel is active!\n\n", pSession->name); pSession->setWriteFd = RSSL_FALSE; if (snapshotSessionProcessChannelActive(pSession) != RSSL_RET_SUCCESS) exit(-1); } pSession->pService = service; return RSSL_RET_SUCCESS; }
/* * Connects to the RSSL server and returns the channel to the caller. * hostname - The hostname of the server to connect to * portno - The port number of the server to connect to * error - The error information in case of failure */ static RsslChannel* connectToRsslServer(RsslConnectionTypes connType, RsslError* error) { RsslChannel* chnl; RsslConnectOptions copts = RSSL_INIT_CONNECT_OPTS; printf("\nAttempting to connect to server %s:%s...\n", srvrHostname, srvrPortNo); copts.connectionInfo.unified.address = srvrHostname; copts.connectionInfo.unified.serviceName = srvrPortNo; copts.connectionInfo.unified.interfaceName = interfaceName; copts.proxyOpts.proxyHostName = proxyHostname; copts.proxyOpts.proxyPort = proxyPort; copts.guaranteedOutputBuffers = 500; copts.connectionType = connType; copts.majorVersion = RSSL_RWF_MAJOR_VERSION; copts.minorVersion = RSSL_RWF_MINOR_VERSION; copts.protocolType = RSSL_RWF_PROTOCOL_TYPE; rsslClearReadOutArgs(&readOutArgs); if ( (chnl = rsslConnect(&copts,error)) != 0) { FD_SET(chnl->socketId,&readfds); FD_SET(chnl->socketId,&exceptfds); if (xmlTrace) { int debugFlags = 0x2C0; RsslTraceOptions traceOptions; rsslClearTraceOptions(&traceOptions); traceOptions.traceMsgFileName = traceOutputFile; traceOptions.traceFlags |= RSSL_TRACE_TO_FILE_ENABLE | RSSL_TRACE_TO_MULTIPLE_FILES | RSSL_TRACE_TO_STDOUT | RSSL_TRACE_READ | RSSL_TRACE_WRITE; traceOptions.traceMsgMaxFileSize = 100000000; rsslIoctl(chnl, (RsslIoctlCodes)RSSL_TRACE, (void *)&traceOptions, error); } printf("\nChannel IPC descriptor = "SOCKET_PRINT_TYPE"\n", chnl->socketId); if (!copts.blocking) { if (!FD_ISSET(chnl->socketId,&wrtfds)) FD_SET(chnl->socketId,&wrtfds); } } return chnl; }
RsslChannel* UPAConsumer::ConnectToRsslServer(const std::string &hostname, const std::string &port, char* interfaceName, RsslConnectionTypes connType, RsslError* error) { RsslChannel* chnl; RsslConnectOptions connectOpts;// = RSSL_INIT_CONNECT_OPTS; //manual initialization for connectOpts based on RSSL_INIT_CONNECT_OPTS - only values that are different than zero memset(&connectOpts,0,sizeof(connectOpts)); connectOpts.pingTimeout=60; connectOpts.guaranteedOutputBuffers=50; connectOpts.numInputBuffers=10; connectOpts.multicastOpts.packetTTL=5; connectOpts.guaranteedOutputBuffers = 500; connectOpts.connectionInfo.unified.address = const_cast<char *>(hostname.c_str()); connectOpts.connectionInfo.unified.serviceName = const_cast<char *>(port.c_str()); connectOpts.connectionInfo.unified.interfaceName = interfaceName; connectOpts.connectionType = connType; connectOpts.majorVersion = RSSL_RWF_MAJOR_VERSION; connectOpts.minorVersion = RSSL_RWF_MINOR_VERSION; connectOpts.protocolType = RSSL_RWF_PROTOCOL_TYPE; if ( (chnl = rsslConnect(&connectOpts,error)) != 0) { FD_SET(chnl->socketId,&readfds_); FD_SET(chnl->socketId,&exceptfds_); t42log_info("Channel IPC descriptor = %d\n", chnl->socketId); if (!connectOpts.blocking) { if (!FD_ISSET(chnl->socketId,&wrtfds_)) FD_SET(chnl->socketId,&wrtfds_); } } return chnl; }
int main(int argc, char **argv) { /* For this simple training app, only a single channel/connection is used for the entire life of this app. */ /* This example uses Unix I/O contents and basic TCP/IP like file descriptor and socket.*/ /* This example suite uses write descriptor in our client/consumer type examples in mainly 2 areas with * the I/O notification mechanism being used: * Details of those functions could be found in API development guide. * 1) rsslInitChannel() function which exchanges various messages to perform necessary UPA transport * negotiations and handshakes to complete channel initialization. * 2) rsslFlush() calls used throughout the application (after module 1a), together with rsslWrite() calls, such * as in sendMessage() function. The write descriptor can be used to indicate when the socketId has write * availability and help with determining when the network is able to accept additional bytes for writing. * * For the RsslChannel initialization process, if using I/O, a client/consumer application should register the * RsslChannel.socketId with the read, write, and exception file descriptor sets. When the write descriptor * alerts the user that the socketId is ready for writing, rsslInitChannel is called (this sends the * initial connection handshake message). When the read file descriptor alerts the user that the socketId * has data to read, rsslInitChannel is called - this typically reads the next portion of the handshake. * This process would continue until the connection is active. * * Typically, calls to rsslInitChannel are driven by I/O on the connection, however this can also be * accomplished by using a timer to periodically call the function or looping on a call until the channel * transitions to active or a failure occurs. Other than any overhead associated with the function call, * there is no harm in calling rsslInitChannel more frequently than required. If no work is required at * the current time, the function will return and indicate that connection is still in progress. */ /* This example suite also uses a clean FD sets and a dirty FD sets for I/O notification. * select() - a system call for examining the status of file_descriptors. * Tells us that there is data to read on the FDs. * Since select() modifies its file descriptor sets, if the call is being used in a loop, then the fd sets must * be reinitialized before each call. Since they act as input/output parameters for the select() system call; * they are read by and modified by the system call. When select() returns, the values have all been modified * to reflect the set of file descriptors ready. So, every time before you call select(), you have to * (re)initialize the fd_set values. Here we maintain 2 sets FD sets: * a) clean FD sets so that we can repeatedly call select call * b) dirty FD sets used in the actual select call (I/O notification mechanism) * Typically, you reset the dirty FD sets to be equal to the clean FD sets before you call select(). */ /****************************************************************************************************************** DECLARING VARIABLES ******************************************************************************************************************/ char srvrHostname[128], srvrPortNo[128], interfaceName[128]; /* clean FD sets so that we can repeatedly call select call */ fd_set cleanReadFds; fd_set cleanExceptFds; fd_set cleanWriteFds; /* dirty FD sets used in the actual select call (I/O notification mechanism) */ fd_set useReadFds; fd_set useExceptFds; fd_set useWriteFds; struct timeval time_interval; int selRet; RsslRet retval = RSSL_RET_FAILURE; RsslError error; RsslConnectOptions cOpts = RSSL_INIT_CONNECT_OPTS; /* RsslInProgInfo Information for the In Progress Connection State */ RsslInProgInfo inProgInfo = RSSL_INIT_IN_PROG_INFO; /* UPA channel management information */ UpaChannelManagementInfo upaChannelManagementInfo; /* For this simple training app, only a single channel/connection is used for the entire life of this app. */ upaChannelManagementInfo.upaChannel = 0; /* the default option parameters */ /* connect to server running on same machine */ snprintf(srvrHostname, 128, "%s", "localhost"); /* server is running on port number 14002 */ snprintf(srvrPortNo, 128, "%s", "14002"); /* use default NIC network interface card to bind to for all inbound and outbound data */ snprintf(interfaceName, 128, "%s", ""); /* User specifies options such as address, port, and interface from the command line. * User can have the flexibilty of specifying any or all of the parameters in any order. */ if (argc > 1) { int i = 1; while (i < argc) { if (strcmp("-h", argv[i]) == 0) { i += 2; snprintf(srvrHostname, 128, "%s", argv[i-1]); } else if (strcmp("-p", argv[i]) == 0) { i += 2; snprintf(srvrPortNo, 128, "%s", argv[i-1]); } else if (strcmp("-i", argv[i]) == 0) { i += 2; snprintf(interfaceName, 128, "%s", argv[i-1]); } else { printf("Error: Unrecognized option: %s\n\n", argv[i]); printf("Usage: %s or\n%s [-h <SrvrHostname>] [-p <SrvrPortNo>] [-i <InterfaceName>] \n", argv[0], argv[0]); exit(RSSL_RET_FAILURE); } } } /****************************************************************************************************************** INITIALIZATION - USING rsslInitialize() ******************************************************************************************************************/ /********************************************************* * Client/Consumer Application Lifecycle Major Step 1: * Initialize UPA Transport using rsslInitialize * The first UPA Transport function that an application should call. This creates and initializes * internal memory and structures, as well as performing any boot strapping for underlying dependencies. * The rsslInitialize function also allows the user to specify the locking model they want applied * to the UPA Transport. *********************************************************/ /* RSSL_LOCK_NONE is used since this is a single threaded application. * For applications with other thread models (RSSL_LOCK_GLOBAL_AND_CHANNEL, RSSL_LOCK_GLOBAL), * see the UPA C developers guide for definitions of other locking models supported by UPA */ if (rsslInitialize(RSSL_LOCK_NONE, &error) != RSSL_RET_SUCCESS) { printf("Error %s (%d) (errno: %d) encountered with rsslInitialize. Error Text: %s\n", rsslRetCodeToString(error.rsslErrorId), error.rsslErrorId, error.sysError, error.text); /* End application */ exit(RSSL_RET_FAILURE); } FD_ZERO(&cleanReadFds); FD_ZERO(&cleanExceptFds); FD_ZERO(&cleanWriteFds); /* populate connect options, then pass to rsslConnect function - * UPA Transport should already be initialized */ /* use standard socket connection */ cOpts.connectionType = RSSL_CONN_TYPE_SOCKET; /*!< (0) Channel is a standard TCP socket connection type */ cOpts.connectionInfo.unified.address = srvrHostname; cOpts.connectionInfo.unified.serviceName = srvrPortNo; cOpts.connectionInfo.unified.interfaceName = interfaceName; /* populate version and protocol with RWF information (found in rsslIterators.h) or protocol specific info */ cOpts.protocolType = RSSL_RWF_PROTOCOL_TYPE; /* Protocol type definition for RWF */ cOpts.majorVersion = RSSL_RWF_MAJOR_VERSION; cOpts.minorVersion = RSSL_RWF_MINOR_VERSION; /****************************************************************************************************************** CONNECTION SETUP - USING rsslConnect() ******************************************************************************************************************/ /********************************************************* * Client/Consumer Application Lifecycle Major Step 2: * Connect using rsslConnect (OS connection establishment handshake) * rsslConnect call Establishes an outbound connection, which can leverage standard sockets, HTTP, * or HTTPS. Returns an RsslChannel that represents the connection to the user. In the event of an error, * NULL is returned and additional information can be found in the RsslError structure. * Connection options are passed in via an RsslConnectOptions structure. *********************************************************/ if ((upaChannelManagementInfo.upaChannel = rsslConnect(&cOpts, &error)) == 0) { printf("Error %s (%d) (errno: %d) encountered with rsslConnect. Error Text: %s\n", rsslRetCodeToString(error.rsslErrorId), error.rsslErrorId, error.sysError, error.text); /* End application, uninitialize to clean up first */ rsslUninitialize(); exit(RSSL_RET_FAILURE); } /* Connection was successful, add socketId to I/O notification mechanism and initialize connection */ /* Typical FD_SET use, this may vary depending on the I/O notification mechanism the application is using */ FD_SET(upaChannelManagementInfo.upaChannel->socketId, &cleanReadFds); FD_SET(upaChannelManagementInfo.upaChannel->socketId, &cleanExceptFds); /* for non-blocking I/O (default), write descriptor is set initially in case this end starts the message * handshakes that rsslInitChannel() performs. Once rsslInitChannel() is called for the first time the * channel can wait on the read descriptor for more messages. Without using the write descriptor, we would * have to keep looping and calling rsslInitChannel to complete the channel initialization process, which * can be CPU-intensive. We will set the write descriptor again if a FD_CHANGE event occurs. */ if (!cOpts.blocking) { if (!FD_ISSET(upaChannelManagementInfo.upaChannel->socketId, &cleanWriteFds)) FD_SET(upaChannelManagementInfo.upaChannel->socketId, &cleanWriteFds); } printf("\nChannel IPC descriptor = %d\n", upaChannelManagementInfo.upaChannel->socketId); /****************************************************************************************************************** MAIN LOOP TO SEE IF RESPONSE RECEIVED FROM PROVIDER ******************************************************************************************************************/ /* Main loop for getting connection active and successful completion of the initialization process * The loop calls select() to wait for notification * Currently, the main loop would exit if an error condition is triggered or * RsslChannel.state transitions to RSSL_CH_STATE_ACTIVE. */ /* *If we want a non-blocking read call to the selector, we use select before read as read is a blocking call but select is not *If we want a blocking read call to the selector, such that we want to wait till we get a message, we should use read without select. *In the program below we will use select(), as it is non-blocking */ while (upaChannelManagementInfo.upaChannel->state != RSSL_CH_STATE_ACTIVE) { useReadFds = cleanReadFds; useWriteFds = cleanWriteFds; useExceptFds = cleanExceptFds; /* Set a timeout value if the provider accepts the connection, but does not initialize it */ /* On Linux platform, select() modifies timeout to reflect the amount of time not slept; * most other implementations do not do this. (POSIX.1-2001 permits either behaviour.) * This causes problems both when Linux code which reads timeout is ported to other operating systems, * and when code is ported to Linux that reuses a struct timeval for multiple select()s * in a loop without reinitializing it. Consider timeout to be undefined after select() returns. * * Note: You should reset the values of your timeout before you call select() every time. */ time_interval.tv_sec = 60; time_interval.tv_usec = 0; /* By employing an I/O notification mechanism (e.g. select, poll), an application can leverage a * non-blocking I/O model, using the I/O notification to alert the application when data is available * to read or when output space is available for writing to. The training examples are written from a * non-blocking I/O perspective. Here, we use the select I/O notification mechanism in our examples. */ selRet = select(FD_SETSIZE, &useReadFds, &useWriteFds, &useExceptFds, &time_interval); if (selRet == 0) { /* select has timed out, close the channel and exit */ /* On success, select() return zero if the timeout expires before anything interesting happens. */ printf("\nChannel initialization has timed out, exiting...\n"); /* Closes channel, cleans up and exits the application. */ closeChannelCleanUpAndExit(upaChannelManagementInfo.upaChannel, RSSL_RET_FAILURE); } else if (selRet > 0) { /* Received a response from the provider. */ /* On success, select() return the number of file descriptors contained in the three returned descriptor sets * (that is, the total number of bits that are set in readfds, writefds, exceptfds) */ /* Wait for channel to become active. After an RsslChannel is returned from the client's rsslConnect or server's rsslAccept call, * the channel may need to continue the initialization process. This additional initialization is required * as long as the RsslChannel.state is RSSL_CH_STATE_INITIALIZING. When using non-blocking I/O, this is the * typical state that an RsslChannel will start from and it may require multiple initialization calls to * transition to active. rsslInitChannel is typically called based on activity on the socketId, though a timer or * looping can be used - the rsslInitChannel function should continue to be called until the * connection becomes active, at which point reading and writing can begin. */ /* Indicates that an RsslChannel requires additional initialization. This initialization is typically additional * connection handshake messages that need to be exchanged. */ /* rsslInitChannel is called if read or write or except is triggered */ if (FD_ISSET(upaChannelManagementInfo.upaChannel->socketId, &useReadFds) || FD_ISSET(upaChannelManagementInfo.upaChannel->socketId, &useWriteFds) || FD_ISSET(upaChannelManagementInfo.upaChannel->socketId, &useExceptFds)) { /* Write descriptor is set initially in case this end starts the message handshakes that rsslInitChannel() performs. * Once rsslInitChannel() is called for the first time the channel can wait on the read descriptor for more messages. * We will set the write descriptor again if a FD_CHANGE event occurs. */ FD_CLR(upaChannelManagementInfo.upaChannel->socketId, &cleanWriteFds); /********************************************************* * Client/Consumer Application Lifecycle Major Step 3: * Initialize until active using rsslInitChannel (UPA Transport connection establishment handshake) * Continues initialization of an RsslChannel. This channel could originate from rsslConnect or rsslAccept. * This function exchanges various messages to perform necessary UPA negotiations and handshakes to * complete channel initialization. * Requires the use of an RsslInProgInfo structure. * The RsslChannel can be used for all additional transport functionality (e.g. reading, writing) once the * state transitions to RSSL_CH_STATE_ACTIVE. If a connection is rejected or initialization fails, * the state will transition to RSSL_CH_STATE_CLOSED. *********************************************************/ /* Internally, the UPA initialization process includes several actions. The initialization includes * any necessary UPA connection handshake exchanges, including any HTTP or HTTPS negotiation. * Compression, ping timeout, and versioning related negotiations also take place during the * initialization process. This process involves exchanging several messages across the connection, * and once all message exchanges have completed the RsslChannel.state will transition. If the connection * is accepted and all types of negotiations completed properly, the RsslChannel.state will become * RSSL_CH_STATE_ACTIVE. If the connection is rejected, either due to some kind of negotiation failure * or because an RsslServer rejected the connection by setting nakMount to RSSL_TRUE, the RsslChannel.state * will become RSSL_CH_STATE_CLOSED. * * Note: * For both client and server channels, more than one call to rsslInitChannel can be required to complete * the channel initialization process. */ if ((retval = rsslInitChannel(upaChannelManagementInfo.upaChannel, &inProgInfo, &error)) < RSSL_RET_SUCCESS) { printf("Error %s (%d) (errno: %d) encountered with rsslInitChannel fd=%d. Error Text: %s\n", rsslRetCodeToString(error.rsslErrorId), error.rsslErrorId, error.sysError, upaChannelManagementInfo.upaChannel->socketId, error.text); /* Closes channel, cleans up and exits the application. */ closeChannelCleanUpAndExit(upaChannelManagementInfo.upaChannel, RSSL_RET_FAILURE); break; } else { /* Handle return code appropriately */ switch (retval) { /*!< (2) Transport Success: Channel initialization is In progress, returned from rsslInitChannel. */ case RSSL_RET_CHAN_INIT_IN_PROGRESS: { /* Initialization is still in progress, check the RsslInProgInfo for additional information */ if (inProgInfo.flags & RSSL_IP_FD_CHANGE) { /* The rsslInitChannel function requires the use of an additional parameter, a RsslInProgInfo structure. * Under certain circumstances, the initialization process may be required to create new or additional underlying connections. * If this occurs, the application is required to unregister the previous socketId and register the new socketId with * the I/O notification mechanism being used. When this occurs, the information is conveyed by the RsslInProgInfo and the RsslInProgFlags. * * RSSL_IP_FD_CHANGE indicates that a socketId change has occurred as a result of this call. The previous socketId has been * stored in RsslInProgInfo.oldSocket so it can be unregistered with the I/O notification mechanism. * The new socketId has been stored in RsslInProgInfo.newSocket so it can be registered with the * I/O notification mechanism. The channel initialization is still in progress and subsequent calls * to rsslInitChannel are required to complete it. */ printf("\nChannel In Progress - New FD: %d Old FD: %d\n",upaChannelManagementInfo.upaChannel->socketId, inProgInfo.oldSocket ); /* File descriptor has changed, unregister old and register new */ FD_CLR(inProgInfo.oldSocket, &cleanReadFds); FD_CLR(inProgInfo.oldSocket, &cleanWriteFds); FD_CLR(inProgInfo.oldSocket, &cleanExceptFds); /* newSocket should equal upaChannelManagementInfo.upaChannel->socketId */ FD_SET(upaChannelManagementInfo.upaChannel->socketId, &cleanReadFds); FD_SET(upaChannelManagementInfo.upaChannel->socketId, &cleanWriteFds); FD_SET(upaChannelManagementInfo.upaChannel->socketId, &cleanExceptFds); } else { printf("\nChannel %d In Progress...\n", upaChannelManagementInfo.upaChannel->socketId); } } break; /* channel connection becomes active! * Once a connection is established and transitions to the RSSL_CH_STATE_ACTIVE state, * this RsslChannel can be used for other transport operations. */ case RSSL_RET_SUCCESS: { printf("\nChannel on fd %d is now active - reading and writing can begin.\n", upaChannelManagementInfo.upaChannel->socketId); /********************************************************* * Connection is now active. The RsslChannel can be used for all additional * transport functionality (e.g. reading, writing) now that the state * transitions to RSSL_CH_STATE_ACTIVE *********************************************************/ /* After channel is active, use UPA Transport utility function rsslGetChannelInfo to query RsslChannel negotiated * parameters and settings and retrieve all current settings. This includes maxFragmentSize and negotiated * compression information as well as many other values. */ if ((retval = rsslGetChannelInfo(upaChannelManagementInfo.upaChannel, &upaChannelManagementInfo.upaChannelInfo, &error)) != RSSL_RET_SUCCESS) { printf("Error %s (%d) (errno: %d) encountered with rsslGetChannelInfo. Error Text: %s\n", rsslRetCodeToString(error.rsslErrorId), error.rsslErrorId, error.sysError, error.text); /* Connection should be closed, return failure */ /* Closes channel, cleans up and exits the application. */ closeChannelCleanUpAndExit(upaChannelManagementInfo.upaChannel, RSSL_RET_FAILURE); } printf( "Channel %d active. Channel Info:\n" " Max Fragment Size: %u\n" " Output Buffers: %u Max, %u Guaranteed\n" " Input Buffers: %u\n" " Send/Recv Buffer Sizes: %u/%u\n" " Ping Timeout: %u\n" " Connected component version: ", upaChannelManagementInfo.upaChannel->socketId, /*!< @brief Socket ID of this UPA channel. */ upaChannelManagementInfo.upaChannelInfo.maxFragmentSize, /*!< @brief This is the max fragment size before fragmentation and reassembly is necessary. */ upaChannelManagementInfo.upaChannelInfo.maxOutputBuffers, /*!< @brief This is the maximum number of output buffers available to the channel. */ upaChannelManagementInfo.upaChannelInfo.guaranteedOutputBuffers, /*!< @brief This is the guaranteed number of output buffers available to the channel. */ upaChannelManagementInfo.upaChannelInfo.numInputBuffers, /*!< @brief This is the number of input buffers available to the channel. */ upaChannelManagementInfo.upaChannelInfo.sysSendBufSize, /*!< @brief This is the systems Send Buffer size. This reports the systems send buffer size respective to the transport type being used (TCP, UDP, etc) */ upaChannelManagementInfo.upaChannelInfo.sysRecvBufSize, /*!< @brief This is the systems Receive Buffer size. This reports the systems receive buffer size respective to the transport type being used (TCP, UDP, etc) */ upaChannelManagementInfo.upaChannelInfo.pingTimeout /*!< @brief This is the value of the negotiated ping timeout */ ); if (upaChannelManagementInfo.upaChannelInfo.componentInfoCount == 0) printf("(No component info)"); else { RsslUInt32 count; for(count = 0; count < upaChannelManagementInfo.upaChannelInfo.componentInfoCount; ++count) { printf("%.*s", upaChannelManagementInfo.upaChannelInfo.componentInfo[count]->componentVersion.length, upaChannelManagementInfo.upaChannelInfo.componentInfo[count]->componentVersion.data); if (count < upaChannelManagementInfo.upaChannelInfo.componentInfoCount - 1) printf(", "); } } printf ("\n\n"); } break; default: /* Error handling */ { printf("\nBad return value fd=%d <%s>\n", upaChannelManagementInfo.upaChannel->socketId, error.text); /* Closes channel, cleans up and exits the application. */ closeChannelCleanUpAndExit(upaChannelManagementInfo.upaChannel, RSSL_RET_FAILURE); } break; } } } } else if (selRet < 0) { /* On error, -1 is returned, and errno is set appropriately; the sets and timeout become undefined */ printf("\nSelect error.\n"); /* Closes channel, cleans up and exits the application. */ closeChannelCleanUpAndExit(upaChannelManagementInfo.upaChannel, RSSL_RET_FAILURE); } } }
RSSL_THREAD_DECLARE(runNIProvConnection, pArg) { ProviderThread *pProviderThread = (ProviderThread*)pArg; RsslError error; TimeValue nextTickTime; RsslInt32 currentTicks = 0; RsslConnectOptions copts; if (pProviderThread->cpuId >= 0) { if (bindThread(pProviderThread->cpuId) != RSSL_RET_SUCCESS) { printf("Error: Failed to bind thread to core %d.\n", pProviderThread->cpuId); exit(-1); } } /* Configure connection options. */ rsslClearConnectOpts(&copts); copts.guaranteedOutputBuffers = niProvPerfConfig.guaranteedOutputBuffers; copts.majorVersion = RSSL_RWF_MAJOR_VERSION; copts.minorVersion = RSSL_RWF_MINOR_VERSION; copts.protocolType = RSSL_RWF_PROTOCOL_TYPE; copts.sysSendBufSize = niProvPerfConfig.sendBufSize; copts.sysRecvBufSize = niProvPerfConfig.recvBufSize; if (niProvPerfConfig.sAddr || niProvPerfConfig.rAddr) { if (niProvPerfConfig.connectionType != RSSL_CONN_TYPE_RELIABLE_MCAST) { printf("Error: Attempting non-multicast segmented connection.\n"); exit(-1); } copts.connectionInfo.segmented.recvAddress = niProvPerfConfig.recvAddr; copts.connectionInfo.segmented.recvServiceName = niProvPerfConfig.recvPort; copts.connectionInfo.segmented.sendAddress = niProvPerfConfig.sendAddr; copts.connectionInfo.segmented.sendServiceName = niProvPerfConfig.sendPort; copts.connectionInfo.segmented.interfaceName = niProvPerfConfig.interfaceName; copts.connectionInfo.unified.unicastServiceName = niProvPerfConfig.unicastPort; copts.connectionType = RSSL_CONN_TYPE_RELIABLE_MCAST; } else { copts.connectionInfo.unified.address = niProvPerfConfig.hostName; copts.connectionInfo.unified.serviceName = niProvPerfConfig.portNo; copts.connectionInfo.unified.interfaceName = niProvPerfConfig.interfaceName; copts.tcp_nodelay = niProvPerfConfig.tcpNoDelay; copts.connectionType = RSSL_CONN_TYPE_SOCKET; } /* Setup connection. */ do { ProviderSession *pProvSession; RsslChannel *pChannel; RsslRet ret; if (niProvPerfConfig.sAddr || niProvPerfConfig.rAddr) printf("\nAttempting segmented connect to server %s:%s %s:%s unicastPort %s...\n", niProvPerfConfig.sendAddr, niProvPerfConfig.sendPort, niProvPerfConfig.recvAddr, niProvPerfConfig.recvPort, niProvPerfConfig.unicastPort); else printf("\nAttempting unified connect to server %s:%s...\n", niProvPerfConfig.hostName, niProvPerfConfig.portNo) ; if (!(pChannel = rsslConnect(&copts, &error))) { printf("rsslConnect() failed: %s(%s)\n", rsslRetCodeToString(error.rsslErrorId), error.text); SLEEP(1); continue; } if (!(pProvSession = providerSessionCreate(pProviderThread, pChannel))) { printf("providerSessionInit() failed\n"); exit(-1); } do { ret = channelHandlerWaitForChannelInit(&pProviderThread->channelHandler, pProvSession->pChannelInfo, 100000); } while (!signal_shutdown && ret == RSSL_RET_CHAN_INIT_IN_PROGRESS); if (ret < RSSL_RET_SUCCESS) { SLEEP(1); continue; } else break; /* Successful initialization. */ } while (!signal_shutdown); nextTickTime = getTimeNano() + nsecPerTick; /* this is the main loop */ while(rtrLikely(!signal_shutdown)) { for (currentTicks = 0; currentTicks < providerThreadConfig.ticksPerSec; ++currentTicks) { providerThreadRead(pProviderThread, nextTickTime); nextTickTime += nsecPerTick; providerThreadSendMsgBurst(pProviderThread, nextTickTime); } providerThreadCheckPings(pProviderThread); } return RSSL_THREAD_RETURN(); }