RSSL_THREAD_DECLARE(runChannelConnectionHandler, pArg)
{

	ProviderThread *pProvThread = (ProviderThread*)pArg;

	TimeValue nextTickTime;
	RsslInt32 currentTicks = 0;

	if (pProvThread->cpuId >= 0)
	{
		if (bindThread(pProvThread->cpuId) != RSSL_RET_SUCCESS)
		{
			printf("Error: Failed to bind thread to core %d.\n", pProvThread->cpuId);
			exit(-1);
		}
	}

	nextTickTime = getTimeNano() + nsecPerTick;

	/* this is the main loop */
	while(rtrLikely(!signal_shutdown))
	{
		for (currentTicks = 0; currentTicks < providerThreadConfig.ticksPerSec; ++currentTicks)
		{
			providerThreadRead(pProvThread, nextTickTime);

			nextTickTime += nsecPerTick;

			providerThreadSendMsgBurst(pProvThread, nextTickTime);

			providerThreadReceiveNewChannels(pProvThread);

		}

		providerThreadCheckPings(pProvThread);

	}

	return RSSL_THREAD_RETURN();
}
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();
}