Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Public Attributes | Private Member Functions | Private Attributes | Friends
nsTimerImpl Class Reference

#include <nsTimerImpl.h>

Inheritance diagram for nsTimerImpl:
Inheritance graph
[legend]
Collaboration diagram for nsTimerImpl:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsTimerImpl ()
void Fire ()
void PostTimerEvent ()
void SetDelayInternal (PRUint32 aDelay)
NS_DECL_ISUPPORTS
NS_DECL_NSITIMER
NS_DECL_NSITIMERINTERNAL
PRInt32 
GetGeneration ()
void init (in nsIObserver aObserver, in unsigned long aDelay, in unsigned long aType)
 Initialize a timer that will fire after the said delay.
void initWithFuncCallback (in nsTimerCallbackFunc aCallback, in voidPtr aClosure, in unsigned long aDelay, in unsigned long aType)
 Initialize a timer to fire after the given millisecond interval.
void initWithCallback (in nsITimerCallback aCallback, in unsigned long aDelay, in unsigned long aType)
 Initialize a timer to fire after the given millisecond interval.
void cancel ()
 Cancel the timer.

Static Public Member Functions

static NS_HIDDEN_ (nsresult) Startup()
static NS_HIDDEN_ (void) Shutdown()

Public Attributes

const short TYPE_ONE_SHOT = 0
 Type of a timer that fires once only.
const short TYPE_REPEATING_SLACK = 1
 After firing, a TYPE_REPEATING_SLACK timer is stopped and not restarted until its callback completes.
const short TYPE_REPEATING_PRECISE = 2
 An TYPE_REPEATING_PRECISE repeating timer aims to have constant period between firings.
attribute unsigned long delay
 The millisecond delay of the timeout.
attribute unsigned long type
 The timer type : one shot or repeating.
readonly attribute voidPtr closure
 The opaque pointer pass to initWithFuncCallback.
readonly attribute nsITimerCallback callback
 The nsITimerCallback object passed to initWithCallback.
attribute boolean idle

Private Member Functions

 ~nsTimerImpl ()
nsresult InitCommon (PRUint32 aType, PRUint32 aDelay)
void ReleaseCallback ()

Private Attributes

nsCOMPtr< nsIThreadmCallingThread
voidmClosure
union {
nsTimerCallbackFunc c
nsITimerCallbacki
nsIObservero
mCallback
PRUint8 mCallbackType
PRPackedBool mIdle
PRUint8 mType
PRPackedBool mFiring
PRBool mArmed
PRBool mCanceled
PRInt32 mGeneration
PRUint32 mDelay
PRIntervalTime mTimeout

Friends

class TimerThread

Detailed Description

Definition at line 88 of file nsTimerImpl.h.


Constructor & Destructor Documentation

Definition at line 141 of file nsTimerImpl.cpp.

                         :
  mClosure(nsnull),
  mCallbackType(CALLBACK_TYPE_UNKNOWN),
  mIdle(PR_TRUE),
  mFiring(PR_FALSE),
  mArmed(PR_FALSE),
  mCanceled(PR_FALSE),
  mGeneration(0),
  mDelay(0),
  mTimeout(0)
{
  // XXXbsmedberg: shouldn't this be in Init()?
  nsIThread::GetCurrent(getter_AddRefs(mCallingThread));

  mCallback.c = nsnull;

#ifdef DEBUG_TIMERS
  mStart = 0;
  mStart2 = 0;
#endif
}

Here is the call graph for this function:

Definition at line 163 of file nsTimerImpl.cpp.

Here is the call graph for this function:


Member Function Documentation

void nsITimer::cancel ( ) [inherited]

Cancel the timer.

This method works on all types, not just on repeating timers -- you might want to cancel a TYPE_ONE_SHOT timer, and even reuse it by re-initializing it (to avoid object destruction and creation costs by conserving one timer instance).

Definition at line 357 of file nsTimerImpl.cpp.

{
  if (mCanceled)
    return;

  PRIntervalTime now = PR_IntervalNow();
#ifdef DEBUG_TIMERS
  if (PR_LOG_TEST(gTimerLog, PR_LOG_DEBUG)) {
    PRIntervalTime a = now - mStart; // actual delay in intervals
    PRUint32       b = PR_MillisecondsToInterval(mDelay); // expected delay in intervals
    PRUint32       d = PR_IntervalToMilliseconds((a > b) ? a - b : b - a); // delta in ms
    sDeltaSum += d;
    sDeltaSumSquared += double(d) * double(d);
    sDeltaNum++;

    PR_LOG(gTimerLog, PR_LOG_DEBUG, ("[this=%p] expected delay time %4dms\n", this, mDelay));
    PR_LOG(gTimerLog, PR_LOG_DEBUG, ("[this=%p] actual delay time   %4dms\n", this, PR_IntervalToMilliseconds(a)));
    PR_LOG(gTimerLog, PR_LOG_DEBUG, ("[this=%p] (mType is %d)       -------\n", this, mType));
    PR_LOG(gTimerLog, PR_LOG_DEBUG, ("[this=%p]     delta           %4dms\n", this, (a > b) ? (PRInt32)d : -(PRInt32)d));

    mStart = mStart2;
    mStart2 = 0;
  }
#endif

  PRIntervalTime timeout = mTimeout;
  if (mType == TYPE_REPEATING_PRECISE) {
    // Precise repeating timers advance mTimeout by mDelay without fail before
    // calling Fire().
    timeout -= PR_MillisecondsToInterval(mDelay);
  }
  gThread->UpdateFilter(mDelay, timeout, now);

  mFiring = PR_TRUE;

  switch (mCallbackType) {
    case CALLBACK_TYPE_FUNC:
      mCallback.c(this, mClosure);
      break;
    case CALLBACK_TYPE_INTERFACE:
      mCallback.i->Notify(this);
      break;
    case CALLBACK_TYPE_OBSERVER:
      mCallback.o->Observe(NS_STATIC_CAST(nsITimer*,this),
                           NS_TIMER_CALLBACK_TOPIC,
                           nsnull);
      break;
    default:;
  }

  mFiring = PR_FALSE;

#ifdef DEBUG_TIMERS
  if (PR_LOG_TEST(gTimerLog, PR_LOG_DEBUG)) {
    PR_LOG(gTimerLog, PR_LOG_DEBUG,
           ("[this=%p] Took %dms to fire timer callback\n",
            this, PR_IntervalToMilliseconds(PR_IntervalNow() - now)));
  }
#endif

  if (mType == TYPE_REPEATING_SLACK) {
    SetDelayInternal(mDelay); // force mTimeout to be recomputed.
    if (gThread)
      gThread->AddTimer(this);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

NS_DECL_ISUPPORTS NS_DECL_NSITIMER NS_DECL_NSITIMERINTERNAL PRInt32 nsTimerImpl::GetGeneration ( ) [inline]

Definition at line 107 of file nsTimerImpl.h.

{ return mGeneration; }

Here is the caller graph for this function:

void nsITimer::init ( in nsIObserver  aObserver,
in unsigned long  aDelay,
in unsigned long  aType 
) [inherited]

Initialize a timer that will fire after the said delay.

A user must keep a reference to this timer till it is is no longer needed or has been cancelled.

Parameters:
aObserverthe callback object that observes the ``timer-callback'' topic with the subject being the timer itself when the timer fires:

observe(nsISupports aSubject, => nsITimer string aTopic, => ``timer-callback'' wstring data => null

Parameters:
aDelaydelay in milliseconds for timer to fire
aTypetimer type per TYPE* consts defined above
nsresult nsTimerImpl::InitCommon ( PRUint32  aType,
PRUint32  aDelay 
) [private]

In case of re-Init, both with and without a preceding Cancel, clear the mCanceled flag and assign a new mGeneration. But first, remove any armed timer from the timer thread's list.

If we are racing with the timer thread to remove this timer and we lose, the RemoveTimer call made here will fail to find this timer in the timer thread's list, and will return false harmlessly. We test mArmed here to avoid the small overhead in RemoveTimer of locking the timer thread and checking its list for this timer. It's safe to test mArmed even though it might be cleared on another thread in the next cycle (or even already be cleared by another CPU whose store hasn't reached our CPU's cache), because RemoveTimer is idempotent.

Definition at line 209 of file nsTimerImpl.cpp.

Here is the call graph for this function:

void nsITimer::initWithCallback ( in nsITimerCallback  aCallback,
in unsigned long  aDelay,
in unsigned long  aType 
) [inherited]

Initialize a timer to fire after the given millisecond interval.

This version takes a function to call and a closure to pass to that function.

Parameters:
aFuncnsITimerCallback interface to call when timer expires
aDelayThe millisecond interval
aTypeTimer type per TYPE* consts defined above
void nsITimer::initWithFuncCallback ( in nsTimerCallbackFunc  aCallback,
in voidPtr  aClosure,
in unsigned long  aDelay,
in unsigned long  aType 
) [inherited]

Initialize a timer to fire after the given millisecond interval.

This version takes a function to call and a closure to pass to that function.

Parameters:
aFuncThe function to invoke
aClosureAn opaque pointer to pass to that function
aDelayThe millisecond interval
aTypeTimer type per TYPE* consts defined above
static nsTimerImpl::NS_HIDDEN_ ( nsresult  ) [static]
static nsTimerImpl::NS_HIDDEN_ ( void  ) [static]

Definition at line 472 of file nsTimerImpl.cpp.

{
  // XXX we may want to reuse the PLEvent in the case of repeating timers.
  TimerEventType* event;

  // construct
  event = PR_NEW(TimerEventType);
  if (!event)
    return;

  // initialize
  PL_InitEvent((PLEvent*)event, this,
               (PLHandleEventProc)handleTimerEvent,
               (PLDestroyEventProc)destroyTimerEvent);

  // Since TimerThread addref'd 'this' for us, we don't need to addref here.
  // We will release in destroyMyEvent.  We do need to copy the generation
  // number from this timer into the event, so we can avoid firing a timer
  // that was re-initialized after being canceled.
  event->mGeneration = mGeneration;

#ifdef DEBUG_TIMERS
  if (PR_LOG_TEST(gTimerLog, PR_LOG_DEBUG)) {
    event->mInitTime = PR_IntervalNow();
  }
#endif

  // If this is a repeating precise timer, we need to calculate the time for
  // the next timer to fire before we make the callback.
  if (mType == TYPE_REPEATING_PRECISE) {
    SetDelayInternal(mDelay);
    if (gThread)
      gThread->AddTimer(this);
  }

  PRThread *thread;
  nsresult rv = mCallingThread->GetPRThread(&thread);
  if (NS_FAILED(rv)) {
    NS_WARNING("Dropping timer event because thread is dead");
    return;
  }

  nsCOMPtr<nsIEventQueue> queue;
  if (gThread)
    gThread->mEventQueueService->GetThreadEventQueue(thread, getter_AddRefs(queue));
  if (queue)
    queue->PostEvent(event);
}

Here is the call graph for this function:

void nsTimerImpl::ReleaseCallback ( ) [inline, private]

Definition at line 114 of file nsTimerImpl.h.

Here is the caller graph for this function:

Definition at line 521 of file nsTimerImpl.cpp.

{
  PRIntervalTime delayInterval = PR_MillisecondsToInterval(aDelay);
  if (delayInterval > DELAY_INTERVAL_MAX) {
    delayInterval = DELAY_INTERVAL_MAX;
    aDelay = PR_IntervalToMilliseconds(delayInterval);
  }

  mDelay = aDelay;

  PRIntervalTime now = PR_IntervalNow();
  if (mTimeout == 0 || mType != TYPE_REPEATING_PRECISE)
    mTimeout = now;

  mTimeout += delayInterval;

#ifdef DEBUG_TIMERS
  if (PR_LOG_TEST(gTimerLog, PR_LOG_DEBUG)) {
    if (mStart == 0)
      mStart = now;
    else
      mStart2 = now;
  }
#endif
}

Here is the caller graph for this function:


Friends And Related Function Documentation

friend class TimerThread [friend]

Definition at line 97 of file nsTimerImpl.h.


Member Data Documentation

The nsITimerCallback object passed to initWithCallback.

Definition at line 189 of file nsITimer.idl.

readonly attribute voidPtr nsITimer::closure [inherited]

The opaque pointer pass to initWithFuncCallback.

Definition at line 184 of file nsITimer.idl.

attribute unsigned long nsITimer::delay [inherited]

The millisecond delay of the timeout.

Definition at line 174 of file nsITimer.idl.

Definition at line 46 of file nsITimerInternal.idl.

Definition at line 146 of file nsTimerImpl.h.

union { ... } nsTimerImpl::mCallback [private]

Definition at line 133 of file nsTimerImpl.h.

Definition at line 122 of file nsTimerImpl.h.

Definition at line 147 of file nsTimerImpl.h.

Definition at line 124 of file nsTimerImpl.h.

Definition at line 154 of file nsTimerImpl.h.

Definition at line 139 of file nsTimerImpl.h.

Definition at line 152 of file nsTimerImpl.h.

Definition at line 134 of file nsTimerImpl.h.

Definition at line 155 of file nsTimerImpl.h.

Definition at line 138 of file nsTimerImpl.h.

attribute unsigned long nsITimer::type [inherited]

The timer type : one shot or repeating.

Definition at line 179 of file nsITimer.idl.

const short nsITimer::TYPE_ONE_SHOT = 0 [inherited]

Type of a timer that fires once only.

Definition at line 93 of file nsITimer.idl.

const short nsITimer::TYPE_REPEATING_PRECISE = 2 [inherited]

An TYPE_REPEATING_PRECISE repeating timer aims to have constant period between firings.

The processing time for each timer callback should not influence the timer period. However, if the processing for the last timer firing could not be completed until just before the next firing occurs, then you could have two timer notification routines being executed in quick succession.

Definition at line 113 of file nsITimer.idl.

const short nsITimer::TYPE_REPEATING_SLACK = 1 [inherited]

After firing, a TYPE_REPEATING_SLACK timer is stopped and not restarted until its callback completes.

Specified timer period will be at least the time between when processing for last firing the callback completes and when the next firing occurs.

This is the preferable repeating type for most situations.

Definition at line 103 of file nsITimer.idl.


The documentation for this class was generated from the following files: