michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef TimerThread_h___ michael@0: #define TimerThread_h___ michael@0: michael@0: #include "nsIObserver.h" michael@0: #include "nsIRunnable.h" michael@0: #include "nsIThread.h" michael@0: michael@0: #include "nsTimerImpl.h" michael@0: #include "nsThreadUtils.h" michael@0: michael@0: #include "nsTArray.h" michael@0: michael@0: #include "mozilla/Atomics.h" michael@0: #include "mozilla/Attributes.h" michael@0: #include "mozilla/Monitor.h" michael@0: michael@0: namespace mozilla { michael@0: class TimeStamp; michael@0: } michael@0: michael@0: class TimerThread MOZ_FINAL : public nsIRunnable, michael@0: public nsIObserver michael@0: { michael@0: public: michael@0: typedef mozilla::Monitor Monitor; michael@0: typedef mozilla::TimeStamp TimeStamp; michael@0: typedef mozilla::TimeDuration TimeDuration; michael@0: michael@0: TimerThread(); michael@0: NS_HIDDEN_(nsresult) InitLocks(); michael@0: michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: NS_DECL_NSIRUNNABLE michael@0: NS_DECL_NSIOBSERVER michael@0: michael@0: NS_HIDDEN_(nsresult) Init(); michael@0: NS_HIDDEN_(nsresult) Shutdown(); michael@0: michael@0: nsresult AddTimer(nsTimerImpl *aTimer); michael@0: nsresult TimerDelayChanged(nsTimerImpl *aTimer); michael@0: nsresult RemoveTimer(nsTimerImpl *aTimer); michael@0: michael@0: void DoBeforeSleep(); michael@0: void DoAfterSleep(); michael@0: michael@0: bool IsOnTimerThread() const michael@0: { michael@0: return mThread == NS_GetCurrentThread(); michael@0: } michael@0: michael@0: private: michael@0: ~TimerThread(); michael@0: michael@0: mozilla::Atomic mInitInProgress; michael@0: bool mInitialized; michael@0: michael@0: // These two internal helper methods must be called while mLock is held. michael@0: // AddTimerInternal returns the position where the timer was added in the michael@0: // list, or -1 if it failed. michael@0: int32_t AddTimerInternal(nsTimerImpl *aTimer); michael@0: bool RemoveTimerInternal(nsTimerImpl *aTimer); michael@0: void ReleaseTimerInternal(nsTimerImpl *aTimer); michael@0: michael@0: nsCOMPtr mThread; michael@0: Monitor mMonitor; michael@0: michael@0: bool mShutdown; michael@0: bool mWaiting; michael@0: bool mNotified; michael@0: bool mSleeping; michael@0: michael@0: nsTArray mTimers; michael@0: }; michael@0: michael@0: struct TimerAdditionComparator { michael@0: TimerAdditionComparator(const mozilla::TimeStamp &aNow, michael@0: nsTimerImpl *aTimerToInsert) : michael@0: now(aNow) michael@0: #ifdef DEBUG michael@0: , timerToInsert(aTimerToInsert) michael@0: #endif michael@0: {} michael@0: michael@0: bool LessThan(nsTimerImpl *fromArray, nsTimerImpl *newTimer) const { michael@0: NS_ABORT_IF_FALSE(newTimer == timerToInsert, "Unexpected timer ordering"); michael@0: michael@0: // Skip any overdue timers. michael@0: return fromArray->mTimeout <= now || michael@0: fromArray->mTimeout <= newTimer->mTimeout; michael@0: } michael@0: michael@0: bool Equals(nsTimerImpl* fromArray, nsTimerImpl* newTimer) const { michael@0: return false; michael@0: } michael@0: michael@0: private: michael@0: const mozilla::TimeStamp &now; michael@0: #ifdef DEBUG michael@0: const nsTimerImpl * const timerToInsert; michael@0: #endif michael@0: }; michael@0: michael@0: #endif /* TimerThread_h___ */