From 24836599cc1db4ee6a26064d0d621bcd77df3ad5 Mon Sep 17 00:00:00 2001 From: chatty Date: Tue, 27 Jul 1993 14:06:46 +0000 Subject: Changed argument of SetAlarm --- utils/Timer.cc | 183 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 138 insertions(+), 45 deletions(-) (limited to 'utils') diff --git a/utils/Timer.cc b/utils/Timer.cc index a8c4a65..0d63bcc 100644 --- a/utils/Timer.cc +++ b/utils/Timer.cc @@ -22,28 +22,8 @@ #include #include -/*?class CcuBaseTimer -The class \typ{CcuBaseTimer} is provided as a base class for timers. -It comes with a derived class \typ{CcuTimer} that can immediately be used. -A timer is created with a period expressed in milliseconds. It will then -periodically call the member function \fun{Handle}, which should be redefined -in derived classes. - -Please note that timers use the signal \var{SIGALRM} and the interval timers -provided by UNIX. -Using them concurrently with system calls such as \fun{sleep} yields -unexpected results. - -The member function \fun{Handle} has a time parameter: it is passed the -current (absolute) time when the signal was received from the system. However, -several timers may be triggered at the same time. -If one of them has a slow \fun{Handle}, the time passed to the next ones no more -corrresponds to the current time. If you want to know the exact time, and you are -not sure of the behaviour of the other timers, it is preferable to use a \typ{CcuTimeStamp}. -?*/ - -/*!class CcuBaseTimer -The implementation of CcuBaseTimer is a bit tricky, because it tries to be fast. +/*!class CcuCoreTimer +The implementation of \typ{CcuCoreTimer} is a bit tricky, because it tries to be fast. Here is the basic idea: active timers are stored in a list, sorted by increasing time-out times. When a signal occurs, all timers whose time-out time is smaller than the current time are notified and removed from the list, then they are inserted again. @@ -59,6 +39,49 @@ and if we make sure that a timer is flagged as inactive when we insert it, all w occurences before the right one will be removed. !*/ +/*?class CcuCoreTimer +Timers are a means to manage or one more periodic tasks in a program. +The class \typ{CcuCoreTimer} is a base class for all kinds of timers. It provides +the basic storing and scheduling of timers, as well as a set of member functions +available to the user, but does not provide the actual, system dependent, timing +scheme. +\typ{CcuCoreTimers} were not designed to be used as is, but only to be derived +in order to implement a specific timing scheme. +For instance, the class \var{CcuBaseTimer} is derived from it and implements +signal-based timers (see next section). Building such derived class is very rare, +and it has only be done for timers based on the Unix \com{select} system call, +in the Unix Channel library. + +A timer is created with a period expressed in milliseconds. It will then +periodically call the member function \fun{Handle}, which should be redefined +in derived classes. +Timers are activated at creation time. They are disactivated, but not destroyed, after +their last pulse. +The member function \fun{Handle} is called when a timer is triggered. +It has a time parameter: it is passed the +current (absolute) time when the signal was received from the system. However, +several timers may be triggered at the same time. +If one of them has a slow \fun{Handle}, the time passed to the next ones no more +corrresponds to the current time. If you want to know the exact time, and you are +not sure of the behaviour of the other timers, it is preferable to use a \typ{CcuTimeStamp}. +?*/ + +/*?class CcuTimerSet +The class \typ{CcuTimerSet} is the data structure used by the class \typ{CcuCoreTimer} +to manage a set of timers. Each different implementation of timers should work +with one such timer set, which is passed to the constructor of \typ{CcuCoreTimer}. +?*/ + +#ifdef DOC +/*? +Create an empty \typ{CcuTimerSet}. +?*/ +CcuTimerSet :: CcuTimerSet () +{ +} + +#endif /* DOC */ + /*! Remove and return the first active timer in the active timer list. @@ -90,7 +113,11 @@ as the first active timer. Finally, the alarm is set up to expire at the expiration time of the new first active timer. !*/ -/*?hidden?*/ +/*? +This function should be called by the underlying timing scheme when one +or more timer has expired. It decides which timers should be triggered, +and prepares the set of timers for the next call. +?*/ void CcuCoreTimer :: Fire (CcuTimerSet* s) { @@ -117,8 +144,10 @@ CcuCoreTimer :: Fire (CcuTimerSet* s) t->Handle (now); } - if (t) - t->SetAlarm (t->NextDate); + if (t) { + CcuTimeStamp then; + t->SetAlarm (t->NextDate - then); + } first = t; } @@ -146,13 +175,13 @@ CcuCoreTimer :: IsInactive (CcuListItem* t) /*? -Create a timer that will send a signal every \var{period} milliseconds, \var{pulses} times. -If \var{pulses} is negative, the timer will send signals forever. -Timers are activated at creation time. They are disactivated, but not destroyed, after -their last signal. +Create a timer with that will time out every \var{period} milliseconds, and at most +\var{pulses} times. This timer will be managed by the timer set \var{s}. +{\em This constructor is only useful when deriving new timers based on a new +timing scheme.} ?*/ -CcuCoreTimer :: CcuCoreTimer (Millisecond period, int pulses, CcuTimerSet* set) -: MySet (set), +CcuCoreTimer :: CcuCoreTimer (Millisecond period, int pulses, CcuTimerSet* s) +: MySet (s), StatusFlag (Active), Period (period), PulsesLeft (pulses) @@ -160,7 +189,7 @@ CcuCoreTimer :: CcuCoreTimer (Millisecond period, int pulses, CcuTimerSet* set) } -/*?hidden?*/ +/*?nodoc?*/ CcuCoreTimer :: ~CcuCoreTimer () { /* the timer has to be stopped in the derived class */ @@ -213,9 +242,9 @@ CcuCoreTimer :: Activate () CcuCoreTimer*& first = MySet->FirstTimer; if (!first) { first = this; - SetAlarm (NextDate); + SetAlarm (Period); } else if (NextDate < first->NextDate ) { - SetAlarm (NextDate); + SetAlarm (Period); MySet->OtherTimers.Prepend (first); first = this; } else @@ -295,8 +324,10 @@ CcuCoreTimer :: Stop () first = MySet->ExtractNextActive (); if (first == 0) StopAlarm (); - else - first->SetAlarm (first->NextDate); + else { + CcuTimeStamp now; + first->SetAlarm (first->NextDate - now); + } } } @@ -318,16 +349,76 @@ CcuCoreTimer :: Wait () } } -/*?hidden?*/ +#ifdef DOC +/*?nextdoc?*/ +Millisecond +CcuCoreTimer :: GetPeriod () const +{ +} + +/*? +Get the period (resp. the number of pulses to go) of a timer. +?*/ +int +CcuCoreTimer :: GetNbPulses () const +{ +} + +/*? +Get the status of a timer. The returned value is \var{Active} or \var{Inactive}. +?*/ +timer_status +CcuCoreTimer :: GetStatus () const +{ +} + +/*?nextdoc?*/ +void +CcuCoreTimer :: SetAlarm (Millisecond delay) +{ +} + +/*? +These two functions hold the implementation of the timing scheme. They +are pure virtual functions, and have to be redefined to implement a specific +scheme. \fun{SetAlarm} should ensure that the function \fun{Fire} will be +called in \var{delay} milliseconds from now. \fun{StopAlarm} should disable such calls. +?*/ +void +CcuCoreTimer :: StopAlarm () +{ +} + +#endif /* DOC */ + +/*? +This virtual function is called when the timer is triggered. It should be +redefined in derived classes to attach a behaviour to a timer. +?*/ void CcuCoreTimer :: Handle (Millisecond) { } + +/*?class CcuBaseTimer +The class \typ{CcuBaseTimer} is provided as a base class for signal-based timers. +It comes with a derived class \typ{CcuTimer} that can be used as is. +A timer is created with a period expressed in milliseconds. It will then +periodically call the member function \fun{Handle}, which should be redefined +in derived classes. + +Please note that signal-based timers use the signal \var{SIGALRM} and the interval timers +provided by UNIX. +Using them concurrently with system calls such as \fun{sleep} yields +unexpected results. +?*/ + + CcuSignalHandler* CcuBaseTimer::TimeOutHandler = 0; CcuTimerSet* CcuBaseTimer::TimerSet = 0; -/*?nodoc?*/ +/*?hidden?*/ void CcuBaseTimer :: ClassInit () { @@ -335,6 +426,12 @@ CcuBaseTimer :: ClassInit () TimerSet = new CcuTimerSet; } +/*? +Create a timer that will send a signal every \var{period} milliseconds, \var{pulses} times. +If \var{pulses} is negative, the timer will send signals forever. +Timers are activated at creation time. They are disactivated, but not destroyed, after +their last pulse. +?*/ CcuBaseTimer :: CcuBaseTimer (Millisecond period, int pulses) : CcuCoreTimer (period, pulses, (TimerSet ? TimerSet : (ClassInit (), TimerSet))) { @@ -344,7 +441,7 @@ CcuBaseTimer :: CcuBaseTimer (Millisecond period, int pulses) Activate (); } -/*?hidden?*/ +/*?nodoc?*/ CcuBaseTimer :: ~CcuBaseTimer () { /* stop it */ @@ -364,11 +461,8 @@ CcuBaseTimer :: StopAlarm () /*?hidden?*/ void -CcuBaseTimer :: SetAlarm (Millisecond when) +CcuBaseTimer :: SetAlarm (Millisecond delay) { - CcuTimeStamp now; - Millisecond delay = when - now; - if (delay <= 0) { StopAlarm (); kill (getpid (), SigAlrm); @@ -400,7 +494,6 @@ CcuBaseTimer :: HandleSignal (int) } - /*?class CcuTimer The class \typ{CcuTimer} is a derived class of \typ{CcuBaseTimer} that can be used without deriving a new class. @@ -424,7 +517,7 @@ CcuTimer :: ~CcuTimer () { } -/*?nodoc?*/ +/*?hidden?*/ void CcuTimer :: Handle (Millisecond ref) { -- cgit v1.1