void WorkerContext::PostMessage(const ValueList &args, KValueRef result)
	{
		Logger *logger = Logger::Get("WorkerContext");
		KValueRef message(args.at(0));

		logger->Debug("PostMessage called with %s", message->DisplayString()->c_str());
		{
			Poco::ScopedLock<Poco::Mutex> lock(mutex);
			messages.push_back(message);
		}
		SendQueuedMessages();
	}
	void WorkerContext::PostMessage(const ValueList &args, SharedValue result)
	{
		Logger *logger = Logger::Get("WorkerContext");
		logger->Debug("PostMessage called");
		try
		{
			Poco::ScopedLock<Poco::Mutex> lock(mutex);
			messages.push_back(args.at(0));
			SendQueuedMessages();
		}
		catch(std::exception &e)
		{
			logger->Error("Error calling onmessage for worker. Error = %s",e.what());
		}
	}
Exemplo n.º 3
0
static DWORD WINAPI DataSendThreadProc(void* data)
{
    // if pipe was closed, we exit the thread
    while (gPipe) {
        DWORD res = WaitForSingleObject(gSendThreadEvent, INFINITE);
        if (gStopSendThread) {
            lf("memtrace.dll: DataSendThreadProc, gStopSendThread is true");
            return 0;
        }
        if (WAIT_OBJECT_0 != res)
            continue;

        SendQueuedMessages();
    }
    lf("memtrace.dll: DataSendThreadProc ended");
    return 0;
}
Exemplo n.º 4
0
static void TerminateSendingThread()
{
    if (!gSendThread)
        return;
    lf("memtrace.dll: TerminateSendingThread() setting gStopSendThread=TRUE and signaling gSendThreadEvent");
    gStopSendThread = true;
    SetEvent(gSendThreadEvent);
    lf("memtrace.dll: TerminateSendingThread() waiting for gSendThread");
    Timer t(true);
    DWORD res = WaitForSingleObject(gSendThread, 5*1024);
    t.Stop();
    lf("%.2f ms to terminate the thread", t.GetTimeInMs());
    if (WAIT_OBJECT_0 == res) {
        lf("memtrace.dll: thread quit by itself");
    } else {
        TerminateThread(gSendThread, 1);
        lf("memtrace.dll: terminated sending thread");
    }
    CloseHandle(gSendThread);
    SendQueuedMessages();
}
Exemplo n.º 5
0
void VuMainThread::Update()
#endif
{
#define NEW_MT_UPDATE 1
#if NEW_MT_UPDATE

	VuGameEntity *game = vuLocalSessionEntity->Game();

	// send and get all messages
	vuTransmitTime = vuxRealTime;

	//START_PROFILE("RT_UPDATE_PU");
	if (game != NULL){
		// sfr: send enqueued position updates, before garbage collector to avoid invalid pointers
		// computes sends allowed and iterate over sessions
		unsigned int allowed = VuMaster::SendsPerPlayer();
		if (vuLocalGame != NULL){
			VuSessionsIterator sit(vuLocalGame);
			for (VuSessionEntity *se = sit.GetFirst();se!=NULL; se = sit.GetNext()){
				if (se != vuLocalSessionEntity.get()){
					se->SendBestEnqueuedPositionUpdatesAndClear(allowed, vuxGameTime);
				}
			}
		}
	}
	//STOP_PROFILE("RT_UPDATE_PU");

	// clear garbage collector
	//START_PROFILE("RT_GC");
	vuCollectionManager->CreateEntitiesAndRunGc();
	//STOP_PROFILE("RT_GC");

	//REPORT_VALUE("messages", nm);
	//extern int nmsgs;
	//REPORT_VALUE("message diff", nmsgs);
	//extern int nSimBase;
	//REPORT_VALUE("sim base", nSimBase);
	//extern DWORD SimObjects;
	//REPORT_VALUE("sim obj", SimObjects);

	// if no game, do dispatch and quite
	if (!game){
#if CAP_DISPATCH
		// send 10 queued messages at most
		if (sendQueue_){
			sendQueue_->DispatchMessages(10, FALSE);
		}
		// 10 ms at most
		VuBaseThread::Update(10);
#else
		if (sendQueue_){
			sendQueue_->DispatchMessages(-1, FALSE);
		}
		messageQueue_->DispatchMessages(-1, FALSE);
#endif
		return;
	}

	//START_PROFILE("VUMAINUP_GROUP");
	// Send low priority messages
	//if (vuLowSendQueue){
	//	vuLowSendQueue->DispatchMessages(-1, FALSE);
	//}

	// our session is dirty, send update
	if (vuLocalSessionEntity->IsDirty ()){
		VuFullUpdateEvent *msg = new VuFullUpdateEvent(vuLocalSessionEntity.get(), vuGlobalGroup);
		msg->RequestOutOfBandTransmit();
		msg->RequestReliableTransmit();
		VuMessageQueue::PostVuMessage(msg);
		vuLocalSessionEntity->ClearDirty();
	}

	// send session and game info every interval
	// time variables
	VU_TIME now = vuxRealTime;  ///< time now
	static VU_TIME last_bg = 0; ///< last broadcast time
	if (now - last_bg > 5000){
		last_bg = now;
		vuLocalSessionEntity->SetTransmissionTime(vuxRealTime);
		VuBroadcastGlobalEvent *msg = new VuBroadcastGlobalEvent(vuLocalSessionEntity.get(), vuGlobalGroup);
		msg->RequestOutOfBandTransmit();
		VuMessageQueue::PostVuMessage(msg);
		vuLocalSessionEntity->SetTransmissionTime(vuxRealTime);
		UpdateGroupData(vuGlobalGroup);
		VuListIterator grp_iter(vuGameList);
		for (
			VuGameEntity* game = (VuGameEntity*)grp_iter.GetFirst(), *nextGame;
			game != NULL; 
			game = nextGame
		){
			nextGame = (VuGameEntity*)grp_iter.GetNext();
			// removes empty games that are not player pool
			if (game->IsLocal() && (game != vuPlayerPoolGroup) && (game->SessionCount() == 0)){
				vuDatabase->Remove(game);
			}
			// broadcast game data if its our game
			if (game->IsLocal() && ((game->LastTransmissionTime() + game->UpdateRate()) < vuxRealTime)){
				if (game->IsDirty()){
					// game dirty, update to everyone
					VuFullUpdateEvent *msg = new VuFullUpdateEvent(game, vuGlobalGroup);
					msg->RequestReliableTransmit();
					msg->RequestOutOfBandTransmit ();
					VuMessageQueue::PostVuMessage(msg);
					game->ClearDirty ();
				}
				else {
					// nothing changed, keep game alive
					VuBroadcastGlobalEvent *msg = new VuBroadcastGlobalEvent(game, vuGlobalGroup);
					msg->RequestOutOfBandTransmit ();
					VuMessageQueue::PostVuMessage(msg);
				}
				game->SetTransmissionTime(vuxRealTime);
			}
			UpdateGroupData(game);
		}
	}
	//STOP_PROFILE("VUMAINUP_GROUP");

	//START_PROFILE("VUMAINUP_SENDDISPATCH");

	if (sendQueue_){
#if CAP_DISPATCH
		// dispatch 10 queued messages at most before sending remotes
		sendQueue_->DispatchMessages(10, FALSE);
#else
		sendQueue_->DispatchMessages(-1, FALSE);
#endif
	}

	// send to remotes and
	SendQueuedMessages();
	//STOP_PROFILE("VUMAINUP_SENDDISPATCH");
	//START_PROFILE("VUMAINUP_GETDISPATCH");
	// get from remotes
	GetMessages();

#if CAP_DISPATCH
	// 10 ms at most
	VuBaseThread::Update(mxTime);
#else
	messageQueue_->DispatchMessages(-1, FALSE);    // flush queue
#endif

	//STOP_PROFILE("VUMAINUP_GETDISPATCH");

#else
	// clear garbage collector
	vuCollectionManager->CreateEntitiesAndFlushGc();

	// zero transmitted bytes
	//ResetXmit();
	// dispatch messages
	messageQueue_->DispatchMessages(-1, FALSE);
	if (vuNormalSendQueue){
		vuNormalSendQueue->DispatchMessages(-1, FALSE);
	}

	// if no game, nothing else
	VuGameEntity  *game = vuLocalSessionEntity->Game();
	if (!game){
	 	return;
	}
	
	// Send low priority messages
	if (vuLowSendQueue){
		vuLowSendQueue->DispatchMessages(-1, FALSE);
	}

	VuEnterCriticalSection ();
	SendQueuedMessages();
	GetMessages();
	VuExitCriticalSection ();
	
	messageQueue_->DispatchMessages(-1, FALSE);    // flush queue
	vuTransmitTime = vuxRealTime;

	// sfr: send enqeued position updates (the ones not sent immediately)
	// compute sends allowed
	// iterate sessions
	unsigned int allowed = VuMaster::SendsPerPlayer(); //TODO
	if (vuLocalGame != NULL){
		VuSessionsIterator sit(vuLocalGame);
		for (VuSessionEntity *se = sit.GetFirst();se!=NULL; se = sit.GetNext()){
			if (se != vuLocalSessionEntity.get()){
				se->SendBestEnqueuedPositionUpdatesAndClear(allowed, vuxGameTime);
			}
		}
	}

	// our session is dirty, send update
	if (vuLocalSessionEntity->IsDirty ()){
		VuFullUpdateEvent *msg = new VuFullUpdateEvent(vuLocalSessionEntity.get(), vuGlobalGroup);
		msg->RequestOutOfBandTransmit();
		msg->RequestReliableTransmit();
		VuMessageQueue::PostVuMessage(msg);
		vuLocalSessionEntity->ClearDirty ();
	}

	// send session and game info every interval
	// time variables
	VU_TIME now = vuxRealTime;  ///< time now
	static VU_TIME last_bg = 0; ///< last broadcast time
	if (now - last_bg > 5000){
		last_bg = now;
		vuLocalSessionEntity->SetTransmissionTime(vuxRealTime);
		VuBroadcastGlobalEvent *msg = new VuBroadcastGlobalEvent(vuLocalSessionEntity.get(), vuGlobalGroup);
		msg->RequestOutOfBandTransmit();
		VuMessageQueue::PostVuMessage(msg);
		vuLocalSessionEntity->SetTransmissionTime(vuxRealTime);
		UpdateGroupData(vuGlobalGroup);
		VuListIterator grp_iter(vuGameList);
		// sfr: removed loop increment from the for, since remove can kill it
		for (
			VuGameEntity* game = (VuGameEntity*)grp_iter.GetFirst(), *nextGame;
			game != NULL; 
			game = nextGame
		){
			nextGame = (VuGameEntity*)grp_iter.GetNext();
			// removes empty games that are not player pool
			if (game->IsLocal() && (game != vuPlayerPoolGroup) && (game->SessionCount() == 0)){
				vuDatabase->Remove(game);
			}
			// broadcast game data if its our game
			if (game->IsLocal() && ((game->LastTransmissionTime() + game->UpdateRate()) < vuxRealTime)){
				if (game->IsDirty()){
					// game dirty, update to everyone
					VuFullUpdateEvent *msg = new VuFullUpdateEvent(game, vuGlobalGroup);
					msg->RequestReliableTransmit();
					msg->RequestOutOfBandTransmit ();
					VuMessageQueue::PostVuMessage(msg);
					game->ClearDirty ();
				}
				else {
					// nothing changed, keep game alive
					VuBroadcastGlobalEvent *msg = new VuBroadcastGlobalEvent(game, vuGlobalGroup);
					msg->RequestOutOfBandTransmit ();
					VuMessageQueue::PostVuMessage(msg);
				}
				game->SetTransmissionTime(vuxRealTime);
			}
			UpdateGroupData(game);
		}
	}
#endif
}