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);
		}
	}
}
Beispiel #2
0
    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());
    }
Beispiel #3
0
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);
        }
    }
}
Beispiel #4
0
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();
		}
	}
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
0
	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;
	}
Beispiel #12
0
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;
}
Beispiel #14
0
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;
}
Beispiel #15
0
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;
}
Beispiel #16
0
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();
	}
}