TimerManager generate double tick per second on some situations

Bug #713742 reported by Alexey Solomin
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
DC++
Confirmed
Medium
Unassigned

Bug Description

Code to fix this error quote below:

int TimerManager::run()
{
 int nextMin = 0;

 ptime now = microsec_clock::universal_time();
 ptime nextSecond = now + seconds(1);
 while (!mtx.timed_lock(nextSecond))
 {
  const uint64_t t = getTick();
  now = microsec_clock::universal_time();
  nextSecond += seconds(1);
  if (nextSecond < now)
  {
   nextSecond = now + seconds(1); // [!] IRainman fix TimerManager error: two tick generated in one second.
  }

  fire(TimerManagerListener::Second(), t);
  if (nextMin++ >= 60)
  {
   fire(TimerManagerListener::Minute(), t);
   nextMin = 0;
  }
 }

 dcdebug("TimerManager done\n");
 return 0;
}

autor FlylinkDC++ Team http://code.google.com/p/flylinkdc

Tags: core
Changed in dcplusplus:
status: New → Confirmed
importance: Undecided → Medium
Revision history for this message
Alexey Solomin (a-rainman) wrote :

 Error in TimerManager. In some situations, it may lead to incorrect operation of speed measuring devices, deadlock, division by zero, and other troubles

ps: ADCH + + probably also contains the error, please fix it ;)

Revision history for this message
Alexey Solomin (a-rainman) wrote :
Revision history for this message
iceman50 (bdcdevel) wrote :

make a patch file of all changes pertinent to this problem don't just give links

Revision history for this message
Big Muscle (bigmuscle) wrote :

I also think that this kind of bug doesn't cause any real problems in DC++. It just can generate TimerManager's ticks later when you e.g. break in debugger etc.

Revision history for this message
Francisco Blas Izquierdo Riera (klondike) (klondike) wrote :

I don't know if this will compile well or not, but basically it replaces the current code by other more simple that still follows the same guidelines (i.e. don't mark unmarked past events more than once but provide a tick count so it can be used to see how long has passed since the last call). The code is made to ensure that the method will be called at most once every second (like the original one) which could cause issues if you trust you will called a fixed amount of times in a fixed time (i.e. you know that between calls at least one second has passed, but to know the exact time you will need to check the tick counter).

The only code that may have issues with this is in ThrottlingManager since it will not take into account these time variations, if instead you want to ensure that the event is fired exactly once per second (which means it may be fired more than once if the clock jumps or the program get blocked for heavy load) then you need a slightly different code, basically replace nextSecond = now + seconds(1); inside the if by nextSecond += seconds(1);

Revision history for this message
Francisco Blas Izquierdo Riera (klondike) (klondike) wrote :

Fixed the calls to the minute timer (the previous one got called 59 times xD) this time we use instead the samethod as with the second timer to get the information.

Again this timer is still lossy, if you prefer a non lossy one (i,e, if suddendly 5 seconds pass it will mark the 5 seconds replace inside the while: nextSecond = now + seconds(1); into nextSecond += seconds(1); and nextMin = now + seconds(60); into nextMin += seconds(60);

Revision history for this message
Alexey Solomin (a-rainman) wrote :

Good day! TimerManager was recently appended, and now looks like this:
# Normalize minute events. Earlier minute was equal to 60 cycles, and
between minute intervals to stretch unpredictably than 60 real
seconds. Now the minute events are generated on time, and do not depend on
Seconds of events.
# Added an hourly event.
# Added does not disable debug message displayed for an extended
previous cycle if it is longer than the second.
The complete code is available to the manager here:
https://code.google.com/p/flylinkdc/source/browse/trunk/client/TimerManager.h?spec=svn13018&r=13018
https://code.google.com/p/flylinkdc/source/browse/trunk/client/TimerManager.cpp?spec=svn13018&r=13018

Fredrik Ullner (ullner)
tags: added: core
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.