Example #1
0
int main(int argc, char **argv)
{
	struct timeval time_interval;
	RsslError error;
	fd_set useRead;
	fd_set useExcept;
	int selRet;
	RsslRet	ret = 0;
	RsslBindOptions sopts;
	RsslErrorInfo rsslErrorInfo;

	TimeValue nextTickTime;
	RsslInt32 currentTicks;
	RsslUInt32 currentRuntimeSec = 0, intervalSeconds = 0;

	TimeValue tickSetStartTime; /* Holds when a paritcular run of ticks started(basically one second's worth)*/

	/* Read in configuration and echo it. */
	initProvPerfConfig(argc, argv);
	printProvPerfConfig(stdout);

	if (!(summaryFile = fopen(provPerfConfig.summaryFilename, "w")))
	{
		printf("Error: Failed to open file '%s'.\n", provPerfConfig.summaryFilename);
		exit(-1);
	}

	printProvPerfConfig(summaryFile); fflush(summaryFile);

	// set up a signal handler so we can cleanup before exit
	signal(SIGINT, signal_handler);

	nsecPerTick = 1000000000LL/(RsslInt64)providerThreadConfig.ticksPerSec;

	_currentTime = getTimeNano();
	nextTickTime = _currentTime;
	currentTicks = 0;

	xmlInitParser();

	FD_ZERO(&readfds);
	FD_ZERO(&exceptfds);

	/* Initialize RSSL */
	if (provPerfConfig.useReactor == RSSL_FALSE) // use UPA Channel
	{
		if (rsslInitialize(providerThreadConfig.threadCount > 1 ? RSSL_LOCK_GLOBAL : RSSL_LOCK_NONE, &error) != RSSL_RET_SUCCESS)
		{
			printf("RsslInitialize failed: %s\n", error.text);
			exit(-1);
		}
	}
	else // use UPA VA Reactor
	{
		/* The locking mode RSSL_LOCK_GLOBAL_AND_CHANNEL is required to use the RsslReactor. */
		if (rsslInitialize(RSSL_LOCK_GLOBAL_AND_CHANNEL, &error) != RSSL_RET_SUCCESS)
		{
			printf("RsslInitialize failed: %s\n", error.text);
			exit(-1);
		}
	}

	/* Initialize run-time */
	rsslProviderRuntime = getTimeNano() + ((RsslInt64)provPerfConfig.runTime * 1000000000LL);

	providerInit(&provider, PROVIDER_INTERACTIVE,
			processActiveChannel,
			processInactiveChannel,
			processMsg);

	if (provPerfConfig.useReactor == RSSL_FALSE) // use UPA Channel
	{
		startProviderThreads(&provider, runChannelConnectionHandler);
	}
	else // use UPA VA Reactor
	{
		startProviderThreads(&provider, runReactorConnectionHandler);
	}


	rsslClearBindOpts(&sopts);

	sopts.guaranteedOutputBuffers = provPerfConfig.guaranteedOutputBuffers;
	sopts.serviceName = provPerfConfig.portNo;
	if(strlen(provPerfConfig.interfaceName)) sopts.interfaceName = provPerfConfig.interfaceName;
	sopts.majorVersion = RSSL_RWF_MAJOR_VERSION;
	sopts.minorVersion = RSSL_RWF_MINOR_VERSION;
	sopts.protocolType = RSSL_RWF_PROTOCOL_TYPE;
	sopts.tcp_nodelay = provPerfConfig.tcpNoDelay;
	sopts.sysSendBufSize = provPerfConfig.sendBufSize;
	sopts.sysRecvBufSize = provPerfConfig.recvBufSize;
	sopts.connectionType = RSSL_CONN_TYPE_SOCKET;
	sopts.maxFragmentSize = provPerfConfig.maxFragmentSize;

	if ((rsslSrvr = rsslBind(&sopts, &error)) == 0)
	{
		printf("rsslBind() failed: %d(%s)\n", error.rsslErrorId, error.text);
		exit(-1);
	}

	printf("Server %d bound to port %d.\n\n", rsslSrvr->socketId, rsslSrvr->portNumber);
	FD_SET(rsslSrvr->socketId,&readfds);
	FD_SET(rsslSrvr->socketId,&exceptfds);

	time_interval.tv_sec = 0; time_interval.tv_usec = 0;
	nextTickTime = getTimeNano() + nsecPerTick;
	currentTicks = 0;
	tickSetStartTime = getTimeNano();

	/* this is the main loop */
	while(1)
	{
		useRead = readfds;
		useExcept = exceptfds;

		/* select() on remaining time for this tick. If we went into the next tick, don't delay at all. */
		_currentTime = getTimeNano();
		time_interval.tv_usec = (long)((_currentTime > nextTickTime) ? 0 : ((nextTickTime - _currentTime)/1000));
		selRet = select(FD_SETSIZE, &useRead, NULL, &useExcept, &time_interval);

		if (selRet == 0)
		{
			/* We've reached the next tick. */
			nextTickTime += nsecPerTick;
			++currentTicks;

			if (currentTicks == providerThreadConfig.ticksPerSec)
			{
				++currentRuntimeSec;
				++intervalSeconds;
				currentTicks = 0;
			}

			if (intervalSeconds == provPerfConfig.writeStatsInterval)
			{
				providerCollectStats(&provider, RSSL_TRUE, provPerfConfig.displayStats, currentRuntimeSec,
						provPerfConfig.writeStatsInterval);
				intervalSeconds = 0;
			}

		}
		else if (selRet > 0)
		{
			if ((rsslSrvr != NULL) && (rsslSrvr->socketId != -1) && (FD_ISSET(rsslSrvr->socketId,&useRead)))
			{
				if (provPerfConfig.useReactor == RSSL_FALSE) // use UPA Channel
				{
					RsslChannel *pChannel;
					RsslError	error;
					RsslAcceptOptions acceptOpts = RSSL_INIT_ACCEPT_OPTS;

					if ((pChannel = rsslAccept(rsslSrvr, &acceptOpts, &error)) == 0)
					{
						printf("rsslAccept: failed <%s>\n",error.text);
					}
					else
					{
						printf("Server %d accepting channel %d.\n\n", rsslSrvr->socketId, pChannel->socketId);
						sendToLeastLoadedThread(pChannel);
					}
				}
				else // use UPA VA Reactor
				{
					if (acceptReactorConnection(rsslSrvr, &rsslErrorInfo) != RSSL_RET_SUCCESS)
					{
						printf("acceptReactorConnection: failed <%s>\n", rsslErrorInfo.rsslError.text);
					}
				}
			}
		}
		else if (selRet < 0)
		{
			/* continue */
#ifdef _WIN32
			if (WSAGetLastError() == WSAEINTR)
				continue;
#else
			if (errno == EINTR)
				continue;
#endif
			perror("select");
			exit(1);
		}

		/* Handle run-time */
		if (_currentTime >= rsslProviderRuntime)
		{
			printf("\nRun time of %u seconds has expired.\n", provPerfConfig.runTime);
			signal_shutdown = RSSL_TRUE; /* Tell other threads to shutdown. */
		}

		if (signal_shutdown == RSSL_TRUE)
		{
			cleanUpAndExit();
		}
	}
}
int main(int argc, char **argv)
{
	RsslError error;
	RsslUInt32 intervalSeconds = 0, currentRuntimeSec = 0;

	/* Read in configuration and echo it. */
	initNIProvPerfConfig(argc, argv);
	printNIProvPerfConfig(stdout);

	if (!(summaryFile = fopen(niProvPerfConfig.summaryFilename, "w")))
	{
		printf("Error: Failed to open file '%s'.\n", niProvPerfConfig.summaryFilename);
		exit(-1);
	}

	printNIProvPerfConfig(summaryFile); fflush(summaryFile);

	providerInit(&provider, PROVIDER_NONINTERACTIVE,
			processActiveChannel,
			processInactiveChannel,
			processMsg);

	// set up a signal handler so we can cleanup before exit
	signal(SIGINT, signal_handler);

	/* Determine update rates on per-tick basis */
	nsecPerTick = 1000000000LL/(RsslInt64)providerThreadConfig.ticksPerSec;

	xmlInitParser();

	/* Initialize RSSL */
	if (rsslInitialize(providerThreadConfig.threadCount > 1 ? RSSL_LOCK_GLOBAL : RSSL_LOCK_NONE, &error) != RSSL_RET_SUCCESS)
	{
		printf("rsslInitialize() failed.\n");
		exit(-1);
	}

	/* Initialize runtime timer */
	rsslProviderRuntime = getTimeNano() + ((RsslInt64)niProvPerfConfig.runTime * 1000000000LL);

	startProviderThreads(&provider, runNIProvConnection);

	/* this is the main loop */
	while(!signal_shutdown)
	{
		SLEEP(1);
		++currentRuntimeSec;
		++intervalSeconds;

		if (intervalSeconds == niProvPerfConfig.writeStatsInterval)
		{
			providerCollectStats(&provider, RSSL_TRUE, niProvPerfConfig.displayStats, 
					currentRuntimeSec, niProvPerfConfig.writeStatsInterval);
			intervalSeconds = 0;
		}
		
		/* Handle runtime. */
		if (getTimeNano() >= rsslProviderRuntime)
		{
			printf("\nRun time of %u seconds has expired.\n\n", niProvPerfConfig.runTime);
			signal_shutdown = RSSL_TRUE; /* Tell other threads to shutdown. */
		}


	}

	cleanUpAndExit();
}