|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef TimerThread_h___ |
|
7 #define TimerThread_h___ |
|
8 |
|
9 #include "nsIObserver.h" |
|
10 #include "nsIRunnable.h" |
|
11 #include "nsIThread.h" |
|
12 |
|
13 #include "nsTimerImpl.h" |
|
14 #include "nsThreadUtils.h" |
|
15 |
|
16 #include "nsTArray.h" |
|
17 |
|
18 #include "mozilla/Atomics.h" |
|
19 #include "mozilla/Attributes.h" |
|
20 #include "mozilla/Monitor.h" |
|
21 |
|
22 namespace mozilla { |
|
23 class TimeStamp; |
|
24 } |
|
25 |
|
26 class TimerThread MOZ_FINAL : public nsIRunnable, |
|
27 public nsIObserver |
|
28 { |
|
29 public: |
|
30 typedef mozilla::Monitor Monitor; |
|
31 typedef mozilla::TimeStamp TimeStamp; |
|
32 typedef mozilla::TimeDuration TimeDuration; |
|
33 |
|
34 TimerThread(); |
|
35 NS_HIDDEN_(nsresult) InitLocks(); |
|
36 |
|
37 NS_DECL_THREADSAFE_ISUPPORTS |
|
38 NS_DECL_NSIRUNNABLE |
|
39 NS_DECL_NSIOBSERVER |
|
40 |
|
41 NS_HIDDEN_(nsresult) Init(); |
|
42 NS_HIDDEN_(nsresult) Shutdown(); |
|
43 |
|
44 nsresult AddTimer(nsTimerImpl *aTimer); |
|
45 nsresult TimerDelayChanged(nsTimerImpl *aTimer); |
|
46 nsresult RemoveTimer(nsTimerImpl *aTimer); |
|
47 |
|
48 void DoBeforeSleep(); |
|
49 void DoAfterSleep(); |
|
50 |
|
51 bool IsOnTimerThread() const |
|
52 { |
|
53 return mThread == NS_GetCurrentThread(); |
|
54 } |
|
55 |
|
56 private: |
|
57 ~TimerThread(); |
|
58 |
|
59 mozilla::Atomic<bool> mInitInProgress; |
|
60 bool mInitialized; |
|
61 |
|
62 // These two internal helper methods must be called while mLock is held. |
|
63 // AddTimerInternal returns the position where the timer was added in the |
|
64 // list, or -1 if it failed. |
|
65 int32_t AddTimerInternal(nsTimerImpl *aTimer); |
|
66 bool RemoveTimerInternal(nsTimerImpl *aTimer); |
|
67 void ReleaseTimerInternal(nsTimerImpl *aTimer); |
|
68 |
|
69 nsCOMPtr<nsIThread> mThread; |
|
70 Monitor mMonitor; |
|
71 |
|
72 bool mShutdown; |
|
73 bool mWaiting; |
|
74 bool mNotified; |
|
75 bool mSleeping; |
|
76 |
|
77 nsTArray<nsTimerImpl*> mTimers; |
|
78 }; |
|
79 |
|
80 struct TimerAdditionComparator { |
|
81 TimerAdditionComparator(const mozilla::TimeStamp &aNow, |
|
82 nsTimerImpl *aTimerToInsert) : |
|
83 now(aNow) |
|
84 #ifdef DEBUG |
|
85 , timerToInsert(aTimerToInsert) |
|
86 #endif |
|
87 {} |
|
88 |
|
89 bool LessThan(nsTimerImpl *fromArray, nsTimerImpl *newTimer) const { |
|
90 NS_ABORT_IF_FALSE(newTimer == timerToInsert, "Unexpected timer ordering"); |
|
91 |
|
92 // Skip any overdue timers. |
|
93 return fromArray->mTimeout <= now || |
|
94 fromArray->mTimeout <= newTimer->mTimeout; |
|
95 } |
|
96 |
|
97 bool Equals(nsTimerImpl* fromArray, nsTimerImpl* newTimer) const { |
|
98 return false; |
|
99 } |
|
100 |
|
101 private: |
|
102 const mozilla::TimeStamp &now; |
|
103 #ifdef DEBUG |
|
104 const nsTimerImpl * const timerToInsert; |
|
105 #endif |
|
106 }; |
|
107 |
|
108 #endif /* TimerThread_h___ */ |