Пример #1
0
static void initializeRefData()
{
	RsslConnectOptions copts;
	time(&endTime);
	endTime += exampleConfig.runTime;

	refDataSessionClear(&refDataSession);

	// connect to ref data server
	printf("Connecting to ref data server %s:%s\n", exampleConfig.refDataServerAddr,
			exampleConfig.refDataServerPort);
	rsslClearConnectOpts(&copts);
	copts.connectionType = RSSL_CONN_TYPE_SOCKET;
	copts.connectionInfo.segmented.recvServiceName = exampleConfig.refDataServerPort;
	copts.connectionInfo.segmented.recvAddress = exampleConfig.refDataServerAddr;
	if (refDataSessionConnect(&refDataSession, &copts) != RSSL_RET_SUCCESS)
		exit(-1);

	if (exampleConfig.xmlRefDataTrace)
	{
		setupXMLTracing(refDataSession.pRsslChannel, exampleConfig.refDataTraceOutputFile);
	}


	// load dictionary
	loadDictionary();
}
Пример #2
0
static void initialize()
{
	RsslConnectOptions copts;
	int i;
	unsigned int j;
	RsslBool foundItem;
	char address[128];
	char port[128];

	RsslRDMService* pService = refDataSession.pService;

	itemListClear(&itemList);

	printf("Searching for the items in the symbol list:\n");

	// Match symbol names in the symbol list
	for (j = 0; j < MAX_ITEMS && strlen(exampleConfig.itemList[j].symbolName) > 0; j++)
	{
		foundItem = RSSL_FALSE;	
		for (i = 0; snapshotServerSession.symbolListEntry[i] != 0 && foundItem == RSSL_FALSE; i++)
		{
			if (strcmp(snapshotServerSession.symbolListEntry[i]->name, exampleConfig.itemList[j].symbolName) == 0)
			{
				foundItem = RSSL_TRUE;
				// Copy the real time stream and gap fill connection information
				itemListAdd(&itemList, snapshotServerSession.symbolListEntry[i]->id, exampleConfig.itemList[j].symbolName, exampleConfig.itemList[j].domainType);
				if (snapshotServerSession.symbolListEntry[i]->streamingChannels[0].domain == exampleConfig.itemList[j].domainType)
				{
					exampleConfig.itemList[j].realTimeChannelId = (RsslUInt32)snapshotServerSession.symbolListEntry[i]->streamingChannels[0].channelId;
				}
				else
				{
					exampleConfig.itemList[j].realTimeChannelId = (RsslUInt32)snapshotServerSession.symbolListEntry[i]->streamingChannels[1].channelId;
				}

				if (snapshotServerSession.symbolListEntry[i]->gapChannels[0].domain == exampleConfig.itemList[j].domainType)
				{
					exampleConfig.itemList[j].gapChannelId = (RsslUInt32)snapshotServerSession.symbolListEntry[i]->gapChannels[0].channelId;
				}
				else
				{
					exampleConfig.itemList[j].gapChannelId = (RsslUInt32)snapshotServerSession.symbolListEntry[i]->gapChannels[1].channelId;
				}
				printf("Item %s found in symbol list\n", exampleConfig.itemList[j].symbolName);
			}
		}
		if (!foundItem)
			printf("Item %s NOT found in symbol list\n", exampleConfig.itemList[j].symbolName);
	}

	printf("\n\nSetting up other connections\n\n");

	if (pService->flags & RDM_SVCF_HAS_SEQ_MCAST)
	{
		if ((pService->seqMCastInfo.flags & RDM_SVC_SMF_HAS_GAP_REC_SERV) && 
				(pService->seqMCastInfo.gapRecoveryServer.address.length > 0))
		{
			printf("Gap Recovery Server:\n\t%.*s " RTR_LLU "\n\n", pService->seqMCastInfo.gapRecoveryServer.address.length,
				pService->seqMCastInfo.gapRecoveryServer.address.data,
				pService->seqMCastInfo.gapRecoveryServer.port);
		}	

		if ((pService->seqMCastInfo.flags & RDM_SVC_SMF_HAS_REF_DATA_SERV) && 
				(pService->seqMCastInfo.refDataServer.address.length > 0))
		{
			printf("Reference Data Server:\n\t%.*s " RTR_LLU "\n\n",  pService->seqMCastInfo.refDataServer.address.length,
				pService->seqMCastInfo.refDataServer.address.data,
				pService->seqMCastInfo.refDataServer.port);
		}	

		// Connect to all the channels only if the verbose option was specified on the command line
		// otherwise connect only to the channels that provide the items of interest.
		if ((pService->seqMCastInfo.flags & RDM_SVC_SMF_HAS_SMC_SERV) && (exampleConfig.realTimeDataVerboseOutput == RSSL_TRUE))
		{
			printf("Streaming Multicast Server(s):\n");

			// When verbose mode is sellected connect to all the real time streams.
			for (j = 0; j < pService->seqMCastInfo.StreamingMCastChanServerCount; j++)
			{
				snprintf(&port[0], 128, RTR_LLU, pService->seqMCastInfo.StreamingMCastChanServerList[j].port);
				snprintf(&address[0], 128, "%.*s", pService->seqMCastInfo.StreamingMCastChanServerList[j].address.length, 
					pService->seqMCastInfo.StreamingMCastChanServerList[j].address.data);

				rsslClearConnectOpts(&copts);

				copts.connectionType = RSSL_CONN_TYPE_SEQ_MCAST;

				if (j == 0)
				{
					copts.connectionInfo.segmented.recvServiceName = 
						exampleConfig.realTimeDataPort[0] ? exampleConfig.realTimeDataPort : &port[0];
					copts.connectionInfo.segmented.recvAddress = 
						exampleConfig.realTimeDataAddr[0] ? exampleConfig.realTimeDataAddr : &address[0];
				}
				else
				{
					copts.connectionInfo.segmented.recvServiceName = &port[0];
					copts.connectionInfo.segmented.recvAddress =  &address[0];
				}
				if (exampleConfig.hasRealTimeInterface)
					copts.connectionInfo.segmented.interfaceName = exampleConfig.realTimeDataIntf;

				snprintf(&pRealTimeFeedSession[j].gapInfo.address[0], 128, "%s", copts.connectionInfo.segmented.recvAddress);
				pRealTimeFeedSession[j].gapInfo.port = atoi(copts.connectionInfo.segmented.recvServiceName);

				printf("\nConnecting to real-time data server %s:%s\n", copts.connectionInfo.segmented.recvAddress,
						copts.connectionInfo.segmented.recvServiceName);
				if (realTimeSessionConnect(&pRealTimeFeedSession[j], &copts) != RSSL_RET_SUCCESS)
					exit(-1);

				// mark the session as connected
				pRealTimeFeedSession[j].connected = RSSL_TRUE;

				// setup tracing if enabled
				if (exampleConfig.xmlRealTimeTrace)
				{
					char tmp[128];

					snprintf(&tmp[0], 128, "%s%d_", exampleConfig.realTimeTraceOutputFile, j);
					setupXMLTracing(pRealTimeFeedSession[j].pRsslChannel, &tmp[0]);
				}
			}

			printf("\n");
		}
		else if ((pService->seqMCastInfo.flags & RDM_SVC_SMF_HAS_SMC_SERV) && (exampleConfig.realTimeDataVerboseOutput == RSSL_FALSE))	
		{
			// We have to find the channels we have to connect to based on the item requested and the symbol list information
			// about the channels
			// we do not want to connect to all the channels received from the Source Directory.
			printf("Streaming Multicast Server(s):\n");

			for (i = 0; exampleConfig.itemList[i].domainType != 0; i++)
			{
				// get the index from the symbol list of the channel information in the source directory message
				int index = exampleConfig.itemList[i].realTimeChannelId;

				// check if this is a duplicate connection
				RsslBool duplicateConnection = RSSL_FALSE;
				for (j = i - 1; j >= 0; j--)
				{
					if (index == exampleConfig.itemList[j].realTimeChannelId)
					{
						duplicateConnection = RSSL_TRUE;
						break;
					}
				}

				if (!duplicateConnection)
				{
					snprintf(&port[0], 128, RTR_LLU, pService->seqMCastInfo.StreamingMCastChanServerList[index].port);
					snprintf(&address[0], 128, "%.*s", pService->seqMCastInfo.StreamingMCastChanServerList[index].address.length, 
							pService->seqMCastInfo.StreamingMCastChanServerList[index].address.data);

					rsslClearConnectOpts(&copts);

					copts.connectionType = RSSL_CONN_TYPE_SEQ_MCAST;

					if (j == 0)
					{
						copts.connectionInfo.segmented.recvServiceName =
							exampleConfig.realTimeDataPort[0] ? exampleConfig.realTimeDataPort : &port[0];
						copts.connectionInfo.segmented.recvAddress =
							exampleConfig.realTimeDataAddr[0] ? exampleConfig.realTimeDataAddr : &address[0];
					}
					else
					{
						copts.connectionInfo.segmented.recvServiceName = &port[0];
						copts.connectionInfo.segmented.recvAddress =  &address[0];
					}
					if (exampleConfig.hasRealTimeInterface)
						copts.connectionInfo.segmented.interfaceName = exampleConfig.realTimeDataIntf;

					snprintf(&pRealTimeFeedSession[i].gapInfo.address[0], 128, "%s", copts.connectionInfo.segmented.recvAddress);
					pRealTimeFeedSession[i].gapInfo.port = atoi(copts.connectionInfo.segmented.recvServiceName);

					printf("\nConnecting to real-time data server %s:%s\n", copts.connectionInfo.segmented.recvAddress,
							copts.connectionInfo.segmented.recvServiceName);
					if (realTimeSessionConnect(&pRealTimeFeedSession[i], &copts) != RSSL_RET_SUCCESS)
						exit(-1);

					// mark the session as connected
					pRealTimeFeedSession[i].connected = RSSL_TRUE;

					// setup tracing if enabled
					if (exampleConfig.xmlRealTimeTrace)
					{
						char tmp[128];

						snprintf(&tmp[0], 128, "%s%d_", exampleConfig.realTimeTraceOutputFile, i);
						setupXMLTracing(pRealTimeFeedSession[i].pRsslChannel, &tmp[0]);
					}
				}
                        }
                        printf("\n");
		}
			
		// connect to gap fill servers
		if (pService->seqMCastInfo.flags & RDM_SVC_SMF_HAS_GMC_SERV && (exampleConfig.gapFillServerVerboseOutput == RSSL_FALSE))
		{
			printf("Gap Fill Server(s):\n");

			for (i = 0; exampleConfig.itemList[i].domainType != 0; i++)
			{
				// get the index from the symbol list of the channel information in the source directory message
				int index = exampleConfig.itemList[i].gapChannelId;

				// check if this is a duplicate connection
				RsslBool duplicateConnection = RSSL_FALSE;
				for (j = i - 1; j >= 0; j--)
				{
					if (index == exampleConfig.itemList[j].gapChannelId)
					{
						duplicateConnection = RSSL_TRUE;
						break;
					}
				}

				if (!duplicateConnection)
				{
					snprintf(&port[0], 128, RTR_LLU, pService->seqMCastInfo.GapMCastChanServerList[index].port);
					snprintf(&address[0], 128, "%.*s", pService->seqMCastInfo.GapMCastChanServerList[index].address.length, 
							pService->seqMCastInfo.GapMCastChanServerList[index].address.data);

					rsslClearConnectOpts(&copts);

					copts.connectionType = RSSL_CONN_TYPE_SEQ_MCAST;

					if (j == 0)
					{
						copts.connectionInfo.segmented.recvServiceName = 
							exampleConfig.gapFillServerPort[0] ? exampleConfig.gapFillServerPort : &port[0];
						copts.connectionInfo.segmented.recvAddress = 
							exampleConfig.gapFillServerAddr[0] ? exampleConfig.gapFillServerAddr : &address[0];
					}
					else
					{
						copts.connectionInfo.segmented.recvServiceName = &port[0];
						copts.connectionInfo.segmented.recvAddress =  &address[0];
					}

					if (exampleConfig.hasGapFillInterface)
						copts.connectionInfo.segmented.interfaceName = exampleConfig.gapFillIntf;


					printf("\nConnecting to gap fill data server %s:%s\n", copts.connectionInfo.segmented.recvAddress,
							copts.connectionInfo.segmented.recvServiceName);
					if (gapFillSessionConnect(&pGapFillSession[i], &copts) != RSSL_RET_SUCCESS)
						exit(-1);

					// mark the session as connected
					pGapFillSession[i].connected = RSSL_TRUE;
				}
			}
			printf("\n");
		}
		else if (pService->seqMCastInfo.flags & RDM_SVC_SMF_HAS_GMC_SERV && (exampleConfig.gapFillServerVerboseOutput == RSSL_TRUE))
		{
			printf("Gap Fill Server(s):\n");

			// When verbose mode is sellected connect to all the gap fill servers.
			for (j = 0; j < pService->seqMCastInfo.GapMCastChanServerCount; j++)
			{
				snprintf(&port[0], 128, RTR_LLU, pService->seqMCastInfo.GapMCastChanServerList[j].port);
				snprintf(&address[0], 128, "%.*s", pService->seqMCastInfo.GapMCastChanServerList[j].address.length, 
					pService->seqMCastInfo.GapMCastChanServerList[j].address.data);

				rsslClearConnectOpts(&copts);

				copts.connectionType = RSSL_CONN_TYPE_SEQ_MCAST;

				if (j == 0)
				{
					copts.connectionInfo.segmented.recvServiceName = 
						exampleConfig.gapFillServerPort[0] ? exampleConfig.gapFillServerPort : &port[0];
					copts.connectionInfo.segmented.recvAddress = 
						exampleConfig.gapFillServerAddr[0] ? exampleConfig.gapFillServerAddr : &address[0];
				}
				else
				{
					copts.connectionInfo.segmented.recvServiceName = &port[0];
					copts.connectionInfo.segmented.recvAddress =  &address[0];
				}
				if (exampleConfig.hasGapFillInterface)
					copts.connectionInfo.segmented.interfaceName = exampleConfig.gapFillIntf;

				printf("\nConnecting to gap fill data server %s:%s\n", copts.connectionInfo.segmented.recvAddress,
						copts.connectionInfo.segmented.recvServiceName);
				if (gapFillSessionConnect(&pGapFillSession[j], &copts) != RSSL_RET_SUCCESS)
					exit(-1);

				// mark the session as connected
				pGapFillSession[j].connected = RSSL_TRUE;

			}

			printf("\n");
		}
	}	

	// Handle error case where there is a problem with the source directory message.
	// Try to use the command line information if specified
	if ((pService->seqMCastInfo.StreamingMCastChanServerCount == 0) && (strlen(&exampleConfig.realTimeDataPort[0]) > 0))
	{
		printf("There was an issue with the Source Directory message.\nWill try to use the command line arguments\n");

		pService->seqMCastInfo.StreamingMCastChanServerCount = 1;
		pRealTimeFeedSession = (RealTimeSession*)malloc(sizeof(RealTimeSession) * pService->seqMCastInfo.StreamingMCastChanServerCount);

		realTimeSessionClear(&pRealTimeFeedSession[0]);
		rsslClearConnectOpts(&copts);

		copts.connectionType = RSSL_CONN_TYPE_SEQ_MCAST;

		copts.connectionInfo.segmented.recvServiceName = exampleConfig.realTimeDataPort;
		copts.connectionInfo.segmented.recvAddress = exampleConfig.realTimeDataAddr;

		if (exampleConfig.hasRealTimeInterface)
			copts.connectionInfo.segmented.interfaceName = exampleConfig.realTimeDataIntf;

		snprintf(&pRealTimeFeedSession[0].gapInfo.address[0], 128, "%s", copts.connectionInfo.segmented.recvAddress);
		pRealTimeFeedSession[0].gapInfo.port = atoi(copts.connectionInfo.segmented.recvServiceName);

		printf("\nConnecting to real-time data server %s:%s\n", copts.connectionInfo.segmented.recvAddress,
				copts.connectionInfo.segmented.recvServiceName);

		if (realTimeSessionConnect(&pRealTimeFeedSession[0], &copts) != RSSL_RET_SUCCESS)
			exit(-1);

		// mark the session as connected
		pRealTimeFeedSession[0].connected = RSSL_TRUE;

		// setup tracing if enabled
		if (exampleConfig.xmlRealTimeTrace)
		{
			char tmp[128];

			snprintf(&tmp[0], 128, "%s%d_", exampleConfig.realTimeTraceOutputFile, 0);
			setupXMLTracing(pRealTimeFeedSession[0].pRsslChannel, &tmp[0]);
		}
	}

	// connect to gap request server
	rsslClearConnectOpts(&copts);
	copts.connectionType = RSSL_CONN_TYPE_SOCKET;
	if (exampleConfig.gapRequestServerPort[0])
	{
		copts.connectionInfo.segmented.recvServiceName = exampleConfig.gapRequestServerPort;
	}
	else
	{
		snprintf(&port[0], 128, RTR_LLU, pService->seqMCastInfo.gapRecoveryServer.port);
		copts.connectionInfo.segmented.recvServiceName = &port[0];
	}
	if (exampleConfig.gapRequestServerAddr[0])
	{
		copts.connectionInfo.segmented.recvAddress = exampleConfig.gapRequestServerAddr;
	}
	else
	{
		snprintf(&address[0], 128, "%.*s", pService->seqMCastInfo.gapRecoveryServer.address.length, pService->seqMCastInfo.gapRecoveryServer.address.data);
		copts.connectionInfo.segmented.recvAddress = &address[0];
	}
	printf("Connecting to gap recovery server %s:%s\n", copts.connectionInfo.segmented.recvAddress, copts.connectionInfo.segmented.recvServiceName);
	if (gapRequestSessionConnect(&gapRequestServerSession, &copts) != RSSL_RET_SUCCESS)
		exit(-1);

	/* Send requests for items */

	snapshotSessionRequestItems(&snapshotServerSession);

}
Пример #3
0
static void initializeSnapshot()
{
	RsslConnectOptions copts;
	unsigned int i;
	char address[128];
	char port[128];

	RsslRDMService* pService = refDataSession.pService;

	printf("\n\nSetting up other connections\n\n");

	if (pService->flags & RDM_SVCF_HAS_SEQ_MCAST)
	{
		if((pService->seqMCastInfo.flags & RDM_SVC_SMF_HAS_SNAPSHOT_SERV) && 
				(pService->seqMCastInfo.snapshotServer.address.length > 0))
		{
			printf("Snapshot Server:\n\t%.*s " RTR_LLU "\n\n", pService->seqMCastInfo.snapshotServer.address.length,
				pService->seqMCastInfo.snapshotServer.address.data,
				pService->seqMCastInfo.snapshotServer.port);
		}	
	}

	snapshotSessionClear(&snapshotServerSession);
	gapRequestSessionClear(&gapRequestServerSession);

	// connect to snapshot server
	rsslClearConnectOpts(&copts);
	copts.connectionType = RSSL_CONN_TYPE_SOCKET;
	if (exampleConfig.snapshotServerPort[0])
	{
		copts.connectionInfo.segmented.recvServiceName = exampleConfig.snapshotServerPort;
	}
	else
	{
		snprintf(&port[0], 128, RTR_LLU, pService->seqMCastInfo.snapshotServer.port);
		copts.connectionInfo.segmented.recvServiceName = &port[0];
	}
	if (exampleConfig.snapshotServerAddr[0])
	{
		copts.connectionInfo.segmented.recvAddress = exampleConfig.snapshotServerAddr;
	}
	else
	{
		snprintf(&address[0], 128, "%.*s", pService->seqMCastInfo.snapshotServer.address.length, pService->seqMCastInfo.snapshotServer.address.data);
		copts.connectionInfo.segmented.recvAddress = &address[0];
	}
	printf("Connecting to snapshot server %s:%s\n", copts.connectionInfo.segmented.recvAddress, copts.connectionInfo.segmented.recvServiceName);
	if (snapshotSessionConnect(&snapshotServerSession, &copts, pService) != RSSL_RET_SUCCESS)
		exit(-1);

	// Initialize the memory for Streaming Real Time Sessions
	if (pService->seqMCastInfo.StreamingMCastChanServerCount != 0)
	{
		pRealTimeFeedSession = (RealTimeSession*)malloc(sizeof(RealTimeSession) * pService->seqMCastInfo.StreamingMCastChanServerCount);
		for (i = 0; i < pService->seqMCastInfo.StreamingMCastChanServerCount; i++)
			realTimeSessionClear(&pRealTimeFeedSession[i]);
	}

	if (pService->seqMCastInfo.GapMCastChanServerCount != 0)
	{
		pGapFillSession = (GapFillSession*)malloc(sizeof(GapFillSession) * pService->seqMCastInfo.GapMCastChanServerCount);

		for (i = 0; i < pService->seqMCastInfo.GapMCastChanServerCount; i++)
			gapFillSessionClear(&pGapFillSession[i]);
	}
}
Пример #4
0
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();
}