1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
---|
2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
---|
3 | *
|
---|
4 | * ***** BEGIN LICENSE BLOCK *****
|
---|
5 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
---|
6 | *
|
---|
7 | * The contents of this file are subject to the Mozilla Public License Version
|
---|
8 | * 1.1 (the "License"); you may not use this file except in compliance with
|
---|
9 | * the License. You may obtain a copy of the License at
|
---|
10 | * http://www.mozilla.org/MPL/
|
---|
11 | *
|
---|
12 | * Software distributed under the License is distributed on an "AS IS" basis,
|
---|
13 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
---|
14 | * for the specific language governing rights and limitations under the
|
---|
15 | * License.
|
---|
16 | *
|
---|
17 | * The Original Code is mozilla.org code.
|
---|
18 | *
|
---|
19 | * The Initial Developer of the Original Code is
|
---|
20 | * Netscape Communications Corporation.
|
---|
21 | * Portions created by the Initial Developer are Copyright (C) 2001
|
---|
22 | * the Initial Developer. All Rights Reserved.
|
---|
23 | *
|
---|
24 | * Contributor(s):
|
---|
25 | * Stuart Parmenter <[email protected]>
|
---|
26 | *
|
---|
27 | * Alternatively, the contents of this file may be used under the terms of
|
---|
28 | * either of the GNU General Public License Version 2 or later (the "GPL"),
|
---|
29 | * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
---|
30 | * in which case the provisions of the GPL or the LGPL are applicable instead
|
---|
31 | * of those above. If you wish to allow use of your version of this file only
|
---|
32 | * under the terms of either the GPL or the LGPL, and not to allow others to
|
---|
33 | * use your version of this file under the terms of the MPL, indicate your
|
---|
34 | * decision by deleting the provisions above and replace them with the notice
|
---|
35 | * and other provisions required by the GPL or the LGPL. If you do not delete
|
---|
36 | * the provisions above, a recipient may use your version of this file under
|
---|
37 | * the terms of any one of the MPL, the GPL or the LGPL.
|
---|
38 | *
|
---|
39 | * ***** END LICENSE BLOCK ***** */
|
---|
40 |
|
---|
41 | #ifndef nsTimerImpl_h___
|
---|
42 | #define nsTimerImpl_h___
|
---|
43 |
|
---|
44 | //#define FORCE_PR_LOG /* Allow logging in the release build */
|
---|
45 |
|
---|
46 | #include "nsITimer.h"
|
---|
47 | #include "nsVoidArray.h"
|
---|
48 | #include "nsIThread.h"
|
---|
49 | #include "nsITimerInternal.h"
|
---|
50 | #include "nsIObserver.h"
|
---|
51 |
|
---|
52 | #include "nsCOMPtr.h"
|
---|
53 |
|
---|
54 | #include "prlog.h"
|
---|
55 |
|
---|
56 | #if defined(PR_LOGGING)
|
---|
57 | static PRLogModuleInfo *gTimerLog = PR_NewLogModule("nsTimerImpl");
|
---|
58 | #define DEBUG_TIMERS 1
|
---|
59 | #else
|
---|
60 | #undef DEBUG_TIMERS
|
---|
61 | #endif
|
---|
62 |
|
---|
63 | #define NS_TIMER_CLASSNAME "Timer"
|
---|
64 | #define NS_TIMER_CID \
|
---|
65 | { /* 5ff24248-1dd2-11b2-8427-fbab44f29bc8 */ \
|
---|
66 | 0x5ff24248, \
|
---|
67 | 0x1dd2, \
|
---|
68 | 0x11b2, \
|
---|
69 | {0x84, 0x27, 0xfb, 0xab, 0x44, 0xf2, 0x9b, 0xc8} \
|
---|
70 | }
|
---|
71 |
|
---|
72 | enum {
|
---|
73 | CALLBACK_TYPE_UNKNOWN = 0,
|
---|
74 | CALLBACK_TYPE_INTERFACE = 1,
|
---|
75 | CALLBACK_TYPE_FUNC = 2,
|
---|
76 | CALLBACK_TYPE_OBSERVER = 3
|
---|
77 | };
|
---|
78 |
|
---|
79 | // Two timer deadlines must differ by less than half the PRIntervalTime domain.
|
---|
80 | #define DELAY_INTERVAL_LIMIT PR_BIT(8 * sizeof(PRIntervalTime) - 1)
|
---|
81 |
|
---|
82 | // Maximum possible delay (XXX rework to use ms rather than interval ticks).
|
---|
83 | #define DELAY_INTERVAL_MAX (DELAY_INTERVAL_LIMIT - 1)
|
---|
84 |
|
---|
85 | // Is interval-time t less than u, even if t has wrapped PRIntervalTime?
|
---|
86 | #define TIMER_LESS_THAN(t, u) ((t) - (u) > DELAY_INTERVAL_LIMIT)
|
---|
87 |
|
---|
88 | class nsTimerImpl : public nsITimer, public nsITimerInternal
|
---|
89 | {
|
---|
90 | public:
|
---|
91 |
|
---|
92 | nsTimerImpl();
|
---|
93 |
|
---|
94 | static NS_HIDDEN_(nsresult) Startup();
|
---|
95 | static NS_HIDDEN_(void) Shutdown();
|
---|
96 |
|
---|
97 | friend class TimerThread;
|
---|
98 |
|
---|
99 | void Fire();
|
---|
100 | void PostTimerEvent();
|
---|
101 | void SetDelayInternal(PRUint32 aDelay);
|
---|
102 |
|
---|
103 | NS_DECL_ISUPPORTS
|
---|
104 | NS_DECL_NSITIMER
|
---|
105 | NS_DECL_NSITIMERINTERNAL
|
---|
106 |
|
---|
107 | PRInt32 GetGeneration() { return mGeneration; }
|
---|
108 |
|
---|
109 | private:
|
---|
110 | ~nsTimerImpl();
|
---|
111 |
|
---|
112 | nsresult InitCommon(PRUint32 aType, PRUint32 aDelay);
|
---|
113 |
|
---|
114 | void ReleaseCallback()
|
---|
115 | {
|
---|
116 | if (mCallbackType == CALLBACK_TYPE_INTERFACE)
|
---|
117 | NS_RELEASE(mCallback.i);
|
---|
118 | else if (mCallbackType == CALLBACK_TYPE_OBSERVER)
|
---|
119 | NS_RELEASE(mCallback.o);
|
---|
120 | }
|
---|
121 |
|
---|
122 | nsCOMPtr<nsIThread> mCallingThread;
|
---|
123 |
|
---|
124 | void * mClosure;
|
---|
125 |
|
---|
126 | union {
|
---|
127 | nsTimerCallbackFunc c;
|
---|
128 | nsITimerCallback * i;
|
---|
129 | nsIObserver * o;
|
---|
130 | } mCallback;
|
---|
131 |
|
---|
132 | // These members are set by Init (called from NS_NewTimer) and never reset.
|
---|
133 | PRUint8 mCallbackType;
|
---|
134 | PRPackedBool mIdle;
|
---|
135 |
|
---|
136 | // These members are set by the initiating thread, when the timer's type is
|
---|
137 | // changed and during the period where it fires on that thread.
|
---|
138 | PRUint8 mType;
|
---|
139 | PRPackedBool mFiring;
|
---|
140 |
|
---|
141 |
|
---|
142 | // Use a PRBool (int) here to isolate loads and stores of these two members
|
---|
143 | // done on various threads under the protection of TimerThread::mLock, from
|
---|
144 | // loads and stores done on the initiating/type-changing/timer-firing thread
|
---|
145 | // to the above PRUint8/PRPackedBool members.
|
---|
146 | PRBool mArmed;
|
---|
147 | PRBool mCanceled;
|
---|
148 |
|
---|
149 | // The generation number of this timer, re-generated each time the timer is
|
---|
150 | // initialized so one-shot timers can be canceled and re-initialized by the
|
---|
151 | // arming thread without any bad race conditions.
|
---|
152 | PRInt32 mGeneration;
|
---|
153 |
|
---|
154 | PRUint32 mDelay;
|
---|
155 | PRIntervalTime mTimeout;
|
---|
156 |
|
---|
157 | #ifdef DEBUG_TIMERS
|
---|
158 | PRIntervalTime mStart, mStart2;
|
---|
159 | static double sDeltaSum;
|
---|
160 | static double sDeltaSumSquared;
|
---|
161 | static double sDeltaNum;
|
---|
162 | #endif
|
---|
163 |
|
---|
164 | };
|
---|
165 |
|
---|
166 | #define NS_TIMERMANAGER_CONTRACTID "@mozilla.org/timer/manager;1"
|
---|
167 | #define NS_TIMERMANAGER_CLASSNAME "Timer Manager"
|
---|
168 | #define NS_TIMERMANAGER_CID \
|
---|
169 | { /* 4fe206fa-1dd2-11b2-8a0a-88bacbecc7d2 */ \
|
---|
170 | 0x4fe206fa, \
|
---|
171 | 0x1dd2, \
|
---|
172 | 0x11b2, \
|
---|
173 | {0x8a, 0x0a, 0x88, 0xba, 0xcb, 0xec, 0xc7, 0xd2} \
|
---|
174 | }
|
---|
175 |
|
---|
176 | #include "nsITimerManager.h"
|
---|
177 |
|
---|
178 | class nsTimerManager : nsITimerManager
|
---|
179 | {
|
---|
180 | public:
|
---|
181 | nsTimerManager();
|
---|
182 |
|
---|
183 | NS_DECL_ISUPPORTS
|
---|
184 | NS_DECL_NSITIMERMANAGER
|
---|
185 |
|
---|
186 | nsresult AddIdleTimer(nsITimer* timer);
|
---|
187 | private:
|
---|
188 | ~nsTimerManager();
|
---|
189 |
|
---|
190 | PRLock *mLock;
|
---|
191 | nsVoidArray mIdleTimers;
|
---|
192 | };
|
---|
193 |
|
---|
194 |
|
---|
195 | #endif /* nsTimerImpl_h___ */
|
---|