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