TTimer.cxx

Go to the documentation of this file.
00001 // @(#)root/base:$Id: TTimer.cxx 28359 2009-04-27 12:36:49Z rdm $
00002 // Author: Fons Rademakers   28/11/96
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TTimer                                                               //
00015 //                                                                      //
00016 // Handles synchronous and a-synchronous timer events.                  //
00017 // 1. synchronous timer is registered into TSystem and is processed     //
00018 //    within the standard ROOT event-loop.                              //
00019 // 2. asynchronous timer is passed to the operating system which sends  //
00020 //    an external signal to ROOT and thus interrupts its event-loop.    //
00021 //                                                                      //
00022 // You can use this class in one of the following ways:                 //
00023 //    - Sub-class TTimer and override the Notify() method.              //
00024 //    - Re-implement the TObject::HandleTimer() method in your class    //
00025 //      and pass a pointer to this object to timer, see the SetObject() //
00026 //      method.                                                         //
00027 //    - Pass an interpreter command to timer, see SetCommand() method.  //
00028 //    - Create a TTimer, connect its Timeout() signal to the            //
00029 //      appropriate methods. Then when the time is up it will emit a    //
00030 //      Timeout() signal and call connected slots.                      //
00031 //                                                                      //
00032 //  Minimum timeout interval is defined in TSystem::ESysConstants as    //
00033 //  kItimerResolution (currently 10 ms).                                //
00034 //                                                                      //
00035 //  Signal/slots example:                                               //
00036 //       TTimer *timer = new TTimer();                                  //
00037 //       timer->Connect("Timeout()", "myObjectClassName",               //
00038 //                      myObject, "TimerDone()");                       //
00039 //       timer->Start(2000, kTRUE);   // 2 seconds single-shot          //
00040 //                                                                      //
00041 //  To emit the Timeout signal repeadetly with minimum timeout:         //
00042 //       timer->Start(0, kFALSE);                                       //
00043 //                                                                      //
00044 //////////////////////////////////////////////////////////////////////////
00045 
00046 #include "TTimer.h"
00047 #include "TSystem.h"
00048 #include "TROOT.h"
00049 
00050 ClassImp(TTimer)
00051 
00052 
00053 class TSingleShotCleaner : public TTimer {
00054 private:
00055    TList  *fGarbage;
00056 public:
00057    TSingleShotCleaner() : TTimer(10, kTRUE) { fGarbage = new TList(); }
00058    virtual ~TSingleShotCleaner() { fGarbage->Delete(); delete fGarbage; }
00059    void TurnOn() {
00060       TObject *obj = (TObject*) gTQSender;
00061       fGarbage->Add(obj);
00062       Reset();
00063       if (gSystem)
00064          gSystem->AddTimer(this);
00065    }
00066    Bool_t Notify() {
00067       fGarbage->Delete();
00068       Reset();
00069       if (gSystem)
00070          gSystem->RemoveTimer(this);
00071       return kTRUE;
00072    }
00073 };
00074 
00075 //______________________________________________________________________________
00076 TTimer::TTimer(Long_t ms, Bool_t mode) : fTime(ms)
00077 {
00078    // Create timer that times out in ms milliseconds. If milliSec is 0
00079    // then the timeout will be the minimum timeout (see TSystem::ESysConstants,
00080    // i.e. 10 ms). If mode == kTRUE then the timer is synchronous else
00081    // a-synchronous. The default is synchronous. Add a timer to the system
00082    // eventloop by calling TurnOn(). Set command to be executed from Notify()
00083    // or set the object whose HandleTimer() method will be called via Notify(),
00084    // derive from TTimer and override Notify() or connect slots to the
00085    // signals Timeout(), TurnOn() and TurnOff().
00086 
00087    fObject      = 0;
00088    fCommand     = "";
00089    fSync        = mode;
00090    fIntSyscalls = kFALSE;
00091    Reset();
00092 }
00093 
00094 //______________________________________________________________________________
00095 TTimer::TTimer(TObject *obj, Long_t ms, Bool_t mode) : fTime(ms)
00096 {
00097    // Create timer that times out in ms milliseconds. If mode == kTRUE then
00098    // the timer is synchronous else a-synchronous. The default is synchronous.
00099    // Add a timer to the system eventloop by calling TurnOn().
00100    // The object's HandleTimer() will be called by Notify().
00101 
00102    fObject      = obj;
00103    fCommand     = "";
00104    fSync        = mode;
00105    fIntSyscalls = kFALSE;
00106    Reset();
00107 }
00108 
00109 //______________________________________________________________________________
00110 TTimer::TTimer(const char *command, Long_t ms, Bool_t mode) : fTime(ms)
00111 {
00112    // Create timer that times out in ms milliseconds. If mode == kTRUE then
00113    // the timer is synchronous else a-synchronous. The default is synchronous.
00114    // Add a timer to the system eventloop by calling TurnOn().
00115    // The interpreter will execute command from Notify().
00116 
00117    fObject      = 0;
00118    fCommand     = command;
00119    fSync        = mode;
00120    fIntSyscalls = kFALSE;
00121    Reset();
00122 }
00123 
00124 //______________________________________________________________________________
00125 Bool_t TTimer::CheckTimer(const TTime &now)
00126 {
00127    // Check if timer timed out.
00128 
00129    if (fAbsTime <= now) {
00130       fTimeout = kTRUE;
00131       Notify();
00132       return kTRUE;
00133    }
00134    return kFALSE;
00135 }
00136 
00137 //______________________________________________________________________________
00138 Bool_t TTimer::Notify()
00139 {
00140    // Notify when timer times out. The timer is always reset. To stop
00141    // the timer call TurnOff().
00142 
00143    Timeout();       // emit Timeout() signal
00144    if (fObject) fObject->HandleTimer(this);
00145    if (fCommand && fCommand.Length() > 0)
00146       gROOT->ProcessLine(fCommand);
00147 
00148    Reset();
00149    return kTRUE;
00150 }
00151 
00152 //______________________________________________________________________________
00153 void TTimer::Reset()
00154 {
00155    // Reset the timer.
00156 
00157    // make sure gSystem exists
00158    ROOT::GetROOT();
00159 
00160    fTimeout = kFALSE;
00161    fAbsTime = fTime;
00162    if (gSystem) {
00163       fAbsTime += gSystem->Now();
00164       if (!fSync) gSystem->ResetTimer(this);
00165    }
00166 }
00167 
00168 //______________________________________________________________________________
00169 void TTimer::SetCommand(const char *command)
00170 {
00171    // Set the interpreter command to be executed at time out. Removes the
00172    // object to be notified (if it was set).
00173 
00174    fObject  = 0;
00175    fCommand = command;
00176 }
00177 
00178 //______________________________________________________________________________
00179 void TTimer::SetObject(TObject *object)
00180 {
00181    // Set the object to be notified  at time out. Removes the command to
00182    // be executed (if it was set).
00183 
00184    fObject  = object;
00185    fCommand = "";
00186 }
00187 
00188 //______________________________________________________________________________
00189 void TTimer::SetInterruptSyscalls(Bool_t set)
00190 {
00191    // When the argument is true the a-synchronous timer (SIGALRM) signal
00192    // handler is set so that interrupted syscalls will not be restarted
00193    // by the kernel. This is typically used in case one wants to put a
00194    // timeout on an I/O operation. By default interrupted syscalls will
00195    // be restarted.
00196 
00197    fIntSyscalls = set;
00198 }
00199 
00200 //___________________________________________________________________
00201 void TTimer::Start(Long_t milliSec, Bool_t singleShot)
00202 {
00203    // Starts the timer with a milliSec timeout. If milliSec is 0
00204    // then the timeout will be the minimum timeout (see TSystem::ESysConstants,
00205    // i.e. 10 ms), if milliSec is -1 then the time interval as previously
00206    // specified (in ctor or SetTime()) will be used.
00207    // If singleShot is kTRUE, the timer will be activated only once,
00208    // otherwise it will continue until it is stopped.
00209    // See also TurnOn(), Stop(), TurnOff().
00210 
00211    if (milliSec >= 0)
00212       SetTime(milliSec);
00213    Reset();
00214    TurnOn();
00215    if (singleShot)
00216       Connect(this, "Timeout()", "TTimer", this, "TurnOff()");
00217    else
00218       Disconnect(this, "Timeout()", this, "TurnOff()");
00219 }
00220 
00221 //______________________________________________________________________________
00222 void TTimer::TurnOff()
00223 {
00224    // Remove timer from system timer list. This requires that a timer
00225    // has been placed in the system timer list (using TurnOn()).
00226    // If a TTimer subclass is placed on another list, override TurnOff() to
00227    // remove the timer from the correct list.
00228 
00229    if (gSystem)
00230       if (gSystem->RemoveTimer(this))
00231          Emit("TurnOff()");
00232 }
00233 
00234 //______________________________________________________________________________
00235 void TTimer::TurnOn()
00236 {
00237    // Add the timer to the system timer list. If a TTimer subclass has to be
00238    // placed on another list, override TurnOn() to add the timer to the correct
00239    // list.
00240 
00241    // might have been set in a previous Start()
00242    Disconnect(this, "Timeout()", this, "TurnOff()");
00243 
00244    if (gSystem) {
00245       gSystem->AddTimer(this);
00246       Emit("TurnOn()");
00247    }
00248 }
00249 
00250 //______________________________________________________________________________
00251 void TTimer::SingleShot(Int_t milliSec, const char *receiver_class,
00252                         void *receiver, const char *method)
00253 {
00254    // This static function calls a slot after a given time interval.
00255    // Created internal timer will be deleted after that.
00256 
00257    TTimer *singleShotTimer = new TTimer(milliSec);
00258    TQObject::Connect(singleShotTimer, "Timeout()",
00259                      receiver_class, receiver, method);
00260 
00261    static TSingleShotCleaner singleShotCleaner;  // single shot timer cleaner
00262 
00263    // gSingleShotCleaner will delete singleShotTimer a
00264    // short period after Timeout() signal is emitted
00265    TQObject::Connect(singleShotTimer, "Timeout()",
00266                      "TTimer", &singleShotCleaner, "TurnOn()");
00267 
00268    singleShotTimer->Start(milliSec, kTRUE);
00269 }

Generated on Tue Jul 5 14:11:24 2011 for ROOT_528-00b_version by  doxygen 1.5.1