diff --git a/bazaar/Timer/Timer.cpp b/bazaar/Timer/Timer.cpp index cc59dc196..ebc0f710c 100644 --- a/bazaar/Timer/Timer.cpp +++ b/bazaar/Timer/Timer.cpp @@ -4,7 +4,7 @@ Timer::Timer() { - granularity = 2; + granularity = 10; run = true; t.Run(THISBACK(TimerThread)); } @@ -73,7 +73,7 @@ void Timer::KillTimeCallback(void *id) { KillTimeCallbacks(id); } -void Timer::TimerProc(dword time) +void Timer::TimerProc(dword time, int & leftsleep) { if(IsPanicMode()) return; @@ -87,7 +87,7 @@ void Timer::TimerProc(dword time) // sTimerLock.Leave(); // //*** // sTimerLock.Enter(); - while(list->GetNext() != list && list->GetNext()->time < time) { + while(list->GetNext() != list && ((leftsleep = (list->GetNext()->time - time)) <= 0)) { TimeEvent *e = list->GetNext(); e->Unlink(); if(e->delay < 0) @@ -98,6 +98,7 @@ void Timer::TimerProc(dword time) delete e; } sTimerLock.Leave(); + if(leftsleep < 0) leftsleep = granularity; //if last done has been processed and no more in queue, ensure good sleep } //SAME API AS IN Ctrl @@ -145,9 +146,11 @@ void Timer::SetTimerGranularity(int ms) void Timer::TimerThread() { + int leftsleep; while(run) { - TimerProc(GetTickCount()); - Sleep(granularity); //granularity + leftsleep = granularity; + TimerProc(GetTickCount(), leftsleep); + Sleep(min(granularity, leftsleep)); } } \ No newline at end of file diff --git a/bazaar/Timer/Timer.h b/bazaar/Timer/Timer.h index 1d766f349..30d8935ca 100644 --- a/bazaar/Timer/Timer.h +++ b/bazaar/Timer/Timer.h @@ -39,7 +39,7 @@ private: void KillTimeCallbacks(void *id, void *idlim); bool ExistsTimeCallback(void *id); void KillTimeCallback(void *id); - void TimerProc(dword time); + void TimerProc(dword time, int & leftsleep); void KillTimeCallbacks(void *id); diff --git a/bazaar/Timer/srcdoc.tpp/Timer$en-us.tpp b/bazaar/Timer/srcdoc.tpp/Timer$en-us.tpp index c4836c7af..e16a2d04c 100644 --- a/bazaar/Timer/srcdoc.tpp/Timer$en-us.tpp +++ b/bazaar/Timer/srcdoc.tpp/Timer$en-us.tpp @@ -18,12 +18,14 @@ things wont get to execution, until a current task is finished, and the timer queue can check whether time has come for the next task.]&] [s0;2 &] -[s0;i150;O0; [2 Because of it, the timing is not as accurate as maybe -desired and can have `"timer glitches/jitter`", depending on -work load..]&] +[s0;i150;O0; [2 Thus, the timing is not as accurate as maybe desired +and can have `"timer glitches/jitter`", depending on work load..]&] [s0;2 &] [s0;i150;O0; [2 Favorite use is to schedule some `*non`*`-timing`-critical -work for `"somewhere`-around`-in`-the`-future`".]&] +work for `"somewhere`-around`-in`-the`-future`", like i.e. observe +some not too strict timing constraints in custom communication +protocols (answer needs to come in within X time, keep alive +messages..)]&] [s0;2 &] [s0;i150;O0; [2 For timing critical stuff, consider using OS native timer means, for WIN32 SetTimer (in windowing environment, using diff --git a/bazaar/TimerTest/TimerTest.h b/bazaar/TimerTest/TimerTest.h index fb9899563..07a9a1aa4 100644 --- a/bazaar/TimerTest/TimerTest.h +++ b/bazaar/TimerTest/TimerTest.h @@ -14,11 +14,16 @@ class TimerTest : public WithLayout { public: typedef TimerTest CLASSNAME; TimerTest(); + ~TimerTest(); + + void Close0(); + virtual void Close(); void Info(const String & s); void Test(); private: Timer t; + Atomic demo; }; #endif diff --git a/bazaar/TimerTest/TimerTest.upp b/bazaar/TimerTest/TimerTest.upp index a7f46d125..d2b55da72 100644 --- a/bazaar/TimerTest/TimerTest.upp +++ b/bazaar/TimerTest/TimerTest.upp @@ -1,3 +1,5 @@ +description "Test for Timer package\377"; + uses CtrlLib, Timer; diff --git a/bazaar/TimerTest/main.cpp b/bazaar/TimerTest/main.cpp index b0447e105..be4c336c4 100644 --- a/bazaar/TimerTest/main.cpp +++ b/bazaar/TimerTest/main.cpp @@ -3,12 +3,17 @@ #define REPEAT_TEST TimerTest::TimerTest() + : demo(0) { CtrlLayout(*this, "Window title"); + + int a = AtomicInc(demo); + ASSERT(a==1); //preload, 1 means running demo mode, 2 means a cb is executing + #ifdef REPEAT_TEST - t.SetTimeCallback(-1000, THISBACK(Test), 0); + t.SetTimeCallback(-100, THISBACK(Test), (int)this); #else - PostCallback(THISBACK(Test)); + t.SetTimeCallback(0, THISBACK(Test), (int)this); #endif } @@ -20,13 +25,41 @@ void TimerTest::Info(const String & s) void TimerTest::Test() { + int a = AtomicInc(demo); + ASSERT(a==2); + Info("O"); + RLOG("O"); + + a = AtomicDec(demo); + if(a<=0) + return; + ASSERT(a>=0); + #ifdef REPEAT_TEST #else - t.SetTimeCallback(1000, THISBACK(Test), 0); + t.SetTimeCallback(100, THISBACK(Test), (int)this); #endif } +void TimerTest::Close() +{ + t.KillTimeCallback((int)this); + int a = AtomicDec(demo); + Thread::Start(THISBACK(Close0)); +} + +void TimerTest::Close0() +{ + while(AtomicRead(demo) > 0) Sleep(1); + ASSERT(AtomicRead(demo)==0); + TopWindow::Close(); +} + +TimerTest::~TimerTest() +{ +} + GUI_APP_MAIN { TimerTest().Run();