void FTimerManager::InternalPauseTimer(FTimerUnifiedDelegate const& InDelegate) { // not currently threadsafe check(IsInGameThread()); int32 TimerIdx; FTimerData const* TimerToPause = FindTimer(InDelegate, &TimerIdx); if( TimerToPause && (TimerToPause->Status != ETimerStatus::Paused) ) { ETimerStatus::Type PreviousStatus = TimerToPause->Status; // Add to Paused list int32 NewIndex = PausedTimerList.Add(*TimerToPause); // Set new status FTimerData &NewTimer = PausedTimerList[NewIndex]; NewTimer.Status = ETimerStatus::Paused; // Remove from previous TArray switch( PreviousStatus ) { case ETimerStatus::Active : // Store time remaining in ExpireTime while paused NewTimer.ExpireTime = NewTimer.ExpireTime - InternalTime; ActiveTimerHeap.HeapRemoveAt(TimerIdx); break; case ETimerStatus::Pending : PendingTimerList.RemoveAtSwap(TimerIdx); break; default : check(false); } } }
void SendRequest() { requestQueue::iterator it; if (m_pDoing || m_pReplies) return; if (m_vsPending.empty()) return; it = m_vsPending.begin(); if (it->second.empty()) { m_vsPending.erase(it); SendRequest(); return; } // When we are called from the timer, we need to remove it. // We can't delete it (segfault on return), thus we // just stop it. The main loop will delete it. CTimer* pTimer = FindTimer("RouteTimeout"); if (pTimer) { pTimer->Stop(); UnlinkTimer(pTimer); } AddTimer( new CRouteTimeout(this, 60, 1, "RouteTimeout", "Recover from missing / wrong server replies")); m_pDoing = it->first; m_pReplies = it->second[0].reply; m_sLastRequest = it->second[0].sLine; PutIRC(it->second[0].sLine); it->second.erase(it->second.begin()); }
void Timers::Execute() { timeval curTime; gettimeofday(&curTime, 0); for (Timer* s = m_firstTimer; s != 0; s = m_firstTimer) { if (CompareTimevals(s->GetNextExecution(), curTime)) break; TimerCbk_t cbk = s->GetCallback(); void* userdata = s->GetUserdata(); s->Update(); int remainingReps = s->GetRemainingRepetitions(); cbk(userdata); if (FindTimer(s)) { DeleteFromList(s); if (remainingReps == 0) delete s; else InsertTimer(s); } } }
void FTimerManager::InternalClearTimer(FTimerHandle const& InHandle) { // not currently threadsafe check(IsInGameThread()); // Skip if the handle is invalid as it would not be found by FindTimer and unbind the current handler if it also used INDEX_NONE. if (!InHandle.IsValid()) { return; } int32 TimerIdx; FTimerData const* const TimerData = FindTimer(InHandle, &TimerIdx); if (TimerData) { InternalClearTimer(TimerIdx, TimerData->Status); } else { // Edge case. We're currently handling this timer when it got cleared. Unbind it to prevent it firing again // in case it was scheduled to fire multiple times. if (CurrentlyExecutingTimer.TimerHandle == InHandle) { CurrentlyExecutingTimer.TimerDelegate.Unbind(); CurrentlyExecutingTimer.TimerHandle.Invalidate(); } } }
void FTimerManager::InternalClearTimer(FTimerUnifiedDelegate const& InDelegate) { // not currently threadsafe check(IsInGameThread()); int32 TimerIdx; FTimerData const* const TimerData = FindTimer(InDelegate, &TimerIdx); if( TimerData ) { switch( TimerData->Status ) { case ETimerStatus::Pending : PendingTimerList.RemoveAtSwap(TimerIdx); break; case ETimerStatus::Active : ActiveTimerHeap.HeapRemoveAt(TimerIdx); break; case ETimerStatus::Paused : PausedTimerList.RemoveAtSwap(TimerIdx); break; default : check(false); } } else { // Edge case. We're currently handling this timer when it got cleared. Unbind it to prevent it firing again // in case it was scheduled to fire multiple times. if (CurrentlyExecutingTimer.TimerDelegate == InDelegate) { CurrentlyExecutingTimer.TimerDelegate.Unbind(); } } }
int AddTimer( TIMER_TYPE type, timer_handler handler, const char *name, int interval, void *userptr ) { Timer *timer; Module *moduleptr; SET_SEGV_LOCATION(); moduleptr = GET_CUR_MODULE(); if( handler == NULL ) { nlog( LOG_WARNING, "Module %s timer %s does not exist", moduleptr->info->name, name ); return NS_FAILURE; } if( FindTimer( name ) ) { nlog( LOG_WARNING, "Module %s timer %s already exists. Not adding.", moduleptr->info->name, name ); return NS_FAILURE; } timer = new_timer( name ); if( timer ) { timer->type = type; timer->interval = interval; timer->lastrun = me.now; timer->moduleptr = moduleptr; timer->handler = handler; timer->userptr = userptr; TimerCalcNextRun(timer, NULL); dlog( DEBUG2, "AddTimer: Module %s added timer %s", moduleptr->info->name, name ); return NS_SUCCESS; } return NS_FAILURE; }
void Timers::Destroy(Timer* timer) { if (FindTimer(timer)) { DeleteFromList(timer); delete timer; } }
void StartAwayNickTimer() { RemTimer("AwayNickTimer"); if (FindTimer("BackNickTimer")) { // Client disconnected before we got set back, so do nothing. RemTimer("BackNickTimer"); return; } AddTimer(new CAwayNickTimer(*this)); }
float FTimerManager::InternalGetTimerRate(FTimerUnifiedDelegate const& InDelegate) const { FTimerData const* const TimerData = FindTimer(InDelegate); if (TimerData) { return TimerData->Rate; } return -1.f; }
bool CModule::AddTimer(CTimer* pTimer) { if ((!pTimer) || (FindTimer(pTimer->GetName()))) { delete pTimer; return false; } if (!m_sTimers.insert(pTimer).second) // Was already added return true; m_pManager->AddCron(pTimer); return true; }
bool FDataScannerImpl::FindExistingChunk(const TMap<uint64, TSet<FGuid>>& ChunkLookup, TMap<FGuid, FSHAHash>& ChunkShaHashes, uint64 ChunkHash, const FRollingHash<WindowSize>& RollingHash, FGuid& OutMatchedChunk) { FStatsScopedTimer FindTimer(StatFindMatchTime); bool bFoundChunkMatch = false; if (ChunkLookup.Contains(ChunkHash)) { FSHAHash ChunkSha; RollingHash.GetWindowData().GetShaHash(ChunkSha); for (FGuid& PotentialMatch : ChunkLookup.FindRef(ChunkHash)) { // Use sha if we have it if (ChunkShaHashes.Contains(PotentialMatch)) { if(ChunkSha == ChunkShaHashes[PotentialMatch]) { bFoundChunkMatch = true; OutMatchedChunk = PotentialMatch; break; } } else { // Otherwise compare data TArray<uint8> SerialBuffer; FStatsScopedTimer DataMatchTimer(StatDataMatchTime); FStatsCollector::Accumulate(StatChunkDataChecks, 1); SerialBuffer.AddUninitialized(WindowSize); RollingHash.GetWindowData().Serialize(SerialBuffer.GetData()); bool ChunkFound = false; if (DataMatcher->CompareData(PotentialMatch, ChunkHash, SerialBuffer, ChunkFound)) { FStatsCollector::Accumulate(StatChunkDataMatches, 1); ChunkShaHashes.Add(PotentialMatch, ChunkSha); bFoundChunkMatch = true; OutMatchedChunk = PotentialMatch; break; } else if(!ChunkFound) { FStatsCollector::Accumulate(StatMissingChunks, 1); } } FStatsCollector::Accumulate(StatHashCollisions, 1); } } return bFoundChunkMatch; }
void Timers::DeleteFromList(Timer* timer) { /* Make sure that the timer is in the list */ if (!FindTimer(timer)) return; /* Unlink the timer */ if (timer->next) timer->next->prev = timer->prev; if (timer->prev) timer->prev->next = timer->next; if (timer == m_firstTimer) m_firstTimer = timer->next; if (timer == m_lastTimer) m_lastTimer = timer->prev; }
float FTimerManager::InternalGetTimerElapsed(FTimerUnifiedDelegate const& InDelegate) const { FTimerData const* const TimerData = FindTimer(InDelegate); if (TimerData) { if( TimerData->Status != ETimerStatus::Active) { // ExpireTime is time remaining for paused timers return (TimerData->Rate - TimerData->ExpireTime); } else { return (TimerData->Rate - (TimerData->ExpireTime - InternalTime)); } } return -1.f; }
BOOL FASTCALL IntKillTimer(PWND Window, UINT_PTR IDEvent, BOOL SystemTimer) { PTIMER pTmr = NULL; TRACE("IntKillTimer Window %x id %p systemtimer %s\n", Window, IDEvent, SystemTimer ? "TRUE" : "FALSE"); TimerEnterExclusive(); pTmr = FindTimer(Window, IDEvent, SystemTimer ? TMRF_SYSTEM : 0); if (pTmr) { RemoveTimer(pTmr); } TimerLeave(); return pTmr ? TRUE : FALSE; }
UINT_PTR FASTCALL IntSetTimer( PWND Window, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, INT Type) { PTIMER pTmr; UINT Ret = IDEvent; LARGE_INTEGER DueTime; DueTime.QuadPart = (LONGLONG)(-5000000); #if 0 /* Windows NT/2k/XP behaviour */ if (Elapse > MAX_ELAPSE_TIME) { TRACE("Adjusting uElapse\n"); Elapse = 1; } #else /* Windows XP SP2 and Windows Server 2003 behaviour */ if (Elapse > MAX_ELAPSE_TIME) { TRACE("Adjusting uElapse\n"); Elapse = MAX_ELAPSE_TIME; } #endif /* Windows 2k/XP and Windows Server 2003 SP1 behaviour */ if (Elapse < 10) { TRACE("Adjusting uElapse\n"); Elapse = 10; } /* Passing an IDEvent of 0 and the SetTimer returns 1. It will create the timer with an ID of 0 */ if ((Window) && (IDEvent == 0)) Ret = 1; pTmr = FindTimer(Window, IDEvent, Type); if ((!pTmr) && (Window == NULL) && (!(Type & TMRF_SYSTEM))) { IntLockWindowlessTimerBitmap(); IDEvent = RtlFindClearBitsAndSet(&WindowLessTimersBitMap, 1, HintIndex); if (IDEvent == (UINT_PTR) -1) { IntUnlockWindowlessTimerBitmap(); ERR("Unable to find a free window-less timer id\n"); EngSetLastError(ERROR_NO_SYSTEM_RESOURCES); ASSERT(FALSE); return 0; } IDEvent = NUM_WINDOW_LESS_TIMERS - IDEvent; Ret = IDEvent; IntUnlockWindowlessTimerBitmap(); } if (!pTmr) { pTmr = CreateTimer(); if (!pTmr) return 0; if (Window && (Type & TMRF_TIFROMWND)) pTmr->pti = Window->head.pti->pEThread->Tcb.Win32Thread; else { if (Type & TMRF_RIT) pTmr->pti = ptiRawInput; else pTmr->pti = PsGetCurrentThreadWin32Thread(); } pTmr->pWnd = Window; pTmr->cmsCountdown = Elapse; pTmr->cmsRate = Elapse; pTmr->pfn = TimerFunc; pTmr->nID = IDEvent; pTmr->flags = Type|TMRF_INIT; } else { pTmr->cmsCountdown = Elapse; pTmr->cmsRate = Elapse; } ASSERT(MasterTimer != NULL); // Start the timer thread! if (TimersListHead.Flink == TimersListHead.Blink) // There is only one timer KeSetTimer(MasterTimer, DueTime, NULL); return Ret; }
bool CModule::RemTimer(const CString& sLabel) { CTimer *pTimer = FindTimer(sLabel); if (!pTimer) return false; return RemTimer(pTimer); }
void FTimerManager::Tick(float DeltaTime) { // @todo, might need to handle long-running case // (e.g. every X seconds, renormalize to InternalTime = 0) InternalTime += DeltaTime; while (ActiveTimerHeap.Num() > 0) { FTimerData& Top = ActiveTimerHeap.HeapTop(); if (InternalTime > Top.ExpireTime) { // Timer has expired! Fire the delegate, then handle potential looping. // Remove it from the heap and store it while we're executing ActiveTimerHeap.HeapPop(CurrentlyExecutingTimer); // Determine how many times the timer may have elapsed (e.g. for large DeltaTime on a short looping timer) int32 const CallCount = CurrentlyExecutingTimer.bLoop ? FMath::Trunc( (InternalTime - CurrentlyExecutingTimer.ExpireTime) / CurrentlyExecutingTimer.Rate ) + 1 : 1; // Now call the function for (int32 CallIdx=0; CallIdx<CallCount; ++CallIdx) { CurrentlyExecutingTimer.TimerDelegate.Execute(); // If timer was cleared in the delegate execution, don't execute further if( !CurrentlyExecutingTimer.TimerDelegate.IsBound() ) { break; } } if( CurrentlyExecutingTimer.bLoop && CurrentlyExecutingTimer.TimerDelegate.IsBound() && // did not get cleared during execution (FindTimer(CurrentlyExecutingTimer.TimerDelegate) == NULL) // did not get manually re-added during execution ) { // Put this timer back on the heap CurrentlyExecutingTimer.ExpireTime += CallCount * CurrentlyExecutingTimer.Rate; ActiveTimerHeap.HeapPush(CurrentlyExecutingTimer); } CurrentlyExecutingTimer.TimerDelegate.Unbind(); } else { // no need to go further down the heap, we can be finished break; } } // Timer has been ticked. LastTickedFrame = GFrameCounter; // If we have any Pending Timers, add them to the Active Queue. if( PendingTimerList.Num() > 0 ) { for(int32 Index=0; Index<PendingTimerList.Num(); Index++) { FTimerData& TimerToActivate = PendingTimerList[Index]; // Convert from time remaining back to a valid ExpireTime TimerToActivate.ExpireTime += InternalTime; TimerToActivate.Status = ETimerStatus::Active; ActiveTimerHeap.HeapPush( TimerToActivate ); } PendingTimerList.Empty(); } }