Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Callbacks and Timers » Time callbacks when ticks overlap
Time callbacks when ticks overlap [message #27554] Fri, 23 July 2010 11:03 Go to next message
Zbych is currently offline  Zbych
Messages: 313
Registered: July 2009
Senior Member
Hi,

I have a problem with time callbacks. They use GetTickCount which overlaps every ~50 days and do all calculations on 32-bit variables. Unfortunately Ctrl::TimerProc doesn't work correctly when (GetTickCount + delay) overlaps.

For example when GetTickCount returns 0xFFFF0000 and I want to set time callback to 2 minutes (0x1D4C0 ms), TimeEvent.time is set to 0x0000D4C0 and Ctrl::TimerProc executes callback every time (because this statement "list->GetNext()->time < time" is true).
This situation is more likely to happen on posix, because GetTickCount returns ticks since the Epoch, not system power on.

My proposition is to change time comparison:
old:
while(list->GetNext() != list && list->GetNext()->time < time) {

new:
while(list->GetNext() != list && ((int)(time - list->GetNext()->time)) > 0) {


Casting to a signed number is a must.

and to remove this (I think it is unnecessary):
	if(e->time > 0x80000000)
		e->time = 0;

Re: Time callbacks when ticks overlap [message #27556 is a reply to message #27554] Fri, 23 July 2010 11:11 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12616
Registered: November 2005
Ultimate Member
Zbych wrote on Fri, 23 July 2010 05:03

Hi,

I have a problem with time callbacks. They use GetTickCount which overlaps every ~50 days and do all calculations on 32-bit variables. Unfortunately Ctrl::TimerProc doesn't work correctly when (GetTickCount + delay) overlaps.

For example when GetTickCount returns 0xFFFF0000 and I want to set time callback to 2 minutes (0x1D4C0 ms), TimeEvent.time is set to 0x0000D4C0 and Ctrl::TimerProc executes callback every time (because this statement "list->GetNext()->time < time" is true).
This situation is more likely to happen on posix, because GetTickCount returns ticks since the Epoch, not system power on.

My proposition is to change time comparison:
old:
while(list->GetNext() != list && list->GetNext()->time < time) {

new:
while(list->GetNext() != list && ((int)(time - list->GetNext()->time)) > 0) {


Casting to a signed number is a must.

and to remove this (I think it is unnecessary):
	if(e->time > 0x80000000)
		e->time = 0;




Thank you. You are right, the code was flawed, yours is correct.

Just to be sure:

void Ctrl::TimerProc(dword time)
{
	if(IsPanicMode())
		return;
	sTimerLock.Enter();
	TimeEvent *list = tevents();
	sTClick = time;
	sTimerLock.Leave();
	Ctrl::CheckMouseCtrl();
	Ctrl::SyncCaret();
	sTimerLock.Enter();
	while(list->GetNext() != list && ((int)(time - list->GetNext()->time)) > 0) {
		TimeEvent *e = list->GetNext();
		e->Unlink();
		if(e->delay < 0)
			sTimeCallback(time - e->delay, e->delay, e->cb, e->id);
		eventid++;
		sTimerLock.Leave();
		e->cb();
		sTimerLock.Enter();
		delete e;
	}
	sTimerLock.Leave();
}

Re: Time callbacks when ticks overlap [message #27568 is a reply to message #27556] Fri, 23 July 2010 14:01 Go to previous messageGo to next message
Zbych is currently offline  Zbych
Messages: 313
Registered: July 2009
Senior Member
luzr wrote on Fri, 23 July 2010 11:11


Just to be sure:
[cut]



That is ok. But there is one more place where time is compared:
static void sTimeCallback(dword time, int delay, Callback cb, void *id) {
[...]
for(e = list->GetNext(); e != list && ((int)(time - e->time) >= 0); e = e->GetNext());
[...]
Re: Time callbacks when ticks overlap [message #27594 is a reply to message #27568] Sun, 25 July 2010 09:31 Go to previous message
mirek is currently offline  mirek
Messages: 12616
Registered: November 2005
Ultimate Member
Zbych wrote on Fri, 23 July 2010 08:01

luzr wrote on Fri, 23 July 2010 11:11


Just to be sure:
[cut]



That is ok. But there is one more place where time is compared:
static void sTimeCallback(dword time, int delay, Callback cb, void *id) {
[...]
for(e = list->GetNext(); e != list && ((int)(time - e->time) >= 0); e = e->GetNext());
[...]



Ops, thanks, missed that one...

That is why I prefer full zipped files posted as patch Smile

Mirek
Previous Topic: Date iterator
Next Topic: how to use timer id? and how to kill a timer
Goto Forum:
  


Current Time: Tue Aug 11 23:43:39 CEST 2020

Total time taken to generate the page: 0.01702 seconds