1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef TimerThread_h___
8 #define TimerThread_h___
10 #include "nsIObserver.h"
11 #include "nsIRunnable.h"
12 #include "nsIThread.h"
14 #include "nsTimerImpl.h"
15 #include "nsThreadUtils.h"
19 #include "mozilla/Atomics.h"
20 #include "mozilla/Attributes.h"
21 #include "mozilla/Monitor.h"
22 #include "mozilla/UniquePtr.h"
28 } // namespace mozilla
30 class TimerThread final
: public mozilla::Runnable
, public nsIObserver
{
32 typedef mozilla::Monitor Monitor
;
33 typedef mozilla::TimeStamp TimeStamp
;
34 typedef mozilla::TimeDuration TimeDuration
;
39 NS_DECL_ISUPPORTS_INHERITED
45 nsresult
AddTimer(nsTimerImpl
* aTimer
);
46 nsresult
RemoveTimer(nsTimerImpl
* aTimer
);
47 TimeStamp
FindNextFireTimeForCurrentThread(TimeStamp aDefault
,
48 uint32_t aSearchBound
);
53 bool IsOnTimerThread() const {
54 return mThread
->SerialEventTarget()->IsOnCurrentThread();
57 uint32_t AllowedEarlyFiringMicroseconds() const;
64 // These internal helper methods must be called while mMonitor is held.
65 // AddTimerInternal returns false if the insertion failed.
66 bool AddTimerInternal(nsTimerImpl
* aTimer
);
67 bool RemoveTimerInternal(nsTimerImpl
* aTimer
);
68 void RemoveLeadingCanceledTimersInternal();
69 void RemoveFirstTimerInternal();
72 already_AddRefed
<nsTimerImpl
> PostTimerEvent(
73 already_AddRefed
<nsTimerImpl
> aTimerRef
);
75 nsCOMPtr
<nsIThread
> mThread
;
83 class Entry final
: public nsTimerImplHolder
{
84 const TimeStamp mTimeout
;
87 Entry(const TimeStamp
& aMinTimeout
, const TimeStamp
& aTimeout
,
88 nsTimerImpl
* aTimerImpl
)
89 : nsTimerImplHolder(aTimerImpl
),
90 mTimeout(std::max(aMinTimeout
, aTimeout
)) {}
92 nsTimerImpl
* Value() const { return mTimerImpl
; }
94 already_AddRefed
<nsTimerImpl
> Take() {
96 mTimerImpl
->SetHolder(nullptr);
98 return mTimerImpl
.forget();
101 static bool UniquePtrLessThan(mozilla::UniquePtr
<Entry
>& aLeft
,
102 mozilla::UniquePtr
<Entry
>& aRight
) {
103 // This is reversed because std::push_heap() sorts the "largest" to
104 // the front of the heap. We want that to be the earliest timer.
105 return aRight
->mTimeout
< aLeft
->mTimeout
;
108 TimeStamp
Timeout() const { return mTimeout
; }
111 nsTArray
<mozilla::UniquePtr
<Entry
>> mTimers
;
112 uint32_t mAllowedEarlyFiringMicroseconds
;
115 #endif /* TimerThread_h___ */