1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/threads/nsTimerImpl.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,158 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef nsTimerImpl_h___ 1.10 +#define nsTimerImpl_h___ 1.11 + 1.12 +//#define FORCE_PR_LOG /* Allow logging in the release build */ 1.13 + 1.14 +#include "nsITimer.h" 1.15 +#include "nsIEventTarget.h" 1.16 +#include "nsIObserver.h" 1.17 + 1.18 +#include "nsCOMPtr.h" 1.19 + 1.20 +#include "prlog.h" 1.21 +#include "mozilla/TimeStamp.h" 1.22 +#include "mozilla/Attributes.h" 1.23 + 1.24 +#ifdef MOZ_TASK_TRACER 1.25 +#include "TracedTaskCommon.h" 1.26 +#endif 1.27 + 1.28 +#if defined(PR_LOGGING) 1.29 +extern PRLogModuleInfo *GetTimerLog(); 1.30 +#define DEBUG_TIMERS 1 1.31 +#else 1.32 +#undef DEBUG_TIMERS 1.33 +#endif 1.34 + 1.35 +#define NS_TIMER_CID \ 1.36 +{ /* 5ff24248-1dd2-11b2-8427-fbab44f29bc8 */ \ 1.37 + 0x5ff24248, \ 1.38 + 0x1dd2, \ 1.39 + 0x11b2, \ 1.40 + {0x84, 0x27, 0xfb, 0xab, 0x44, 0xf2, 0x9b, 0xc8} \ 1.41 +} 1.42 + 1.43 +enum { 1.44 + CALLBACK_TYPE_UNKNOWN = 0, 1.45 + CALLBACK_TYPE_INTERFACE = 1, 1.46 + CALLBACK_TYPE_FUNC = 2, 1.47 + CALLBACK_TYPE_OBSERVER = 3 1.48 +}; 1.49 + 1.50 +class nsTimerImpl MOZ_FINAL : public nsITimer 1.51 +{ 1.52 +public: 1.53 + typedef mozilla::TimeStamp TimeStamp; 1.54 + 1.55 + nsTimerImpl(); 1.56 + 1.57 + static NS_HIDDEN_(nsresult) Startup(); 1.58 + static NS_HIDDEN_(void) Shutdown(); 1.59 + 1.60 + friend class TimerThread; 1.61 + friend struct TimerAdditionComparator; 1.62 + 1.63 + void Fire(); 1.64 + // If a failure is encountered, the reference is returned to the caller 1.65 + static already_AddRefed<nsTimerImpl> PostTimerEvent( 1.66 + already_AddRefed<nsTimerImpl> aTimerRef); 1.67 + void SetDelayInternal(uint32_t aDelay); 1.68 + 1.69 + NS_DECL_THREADSAFE_ISUPPORTS 1.70 + NS_DECL_NSITIMER 1.71 + 1.72 + int32_t GetGeneration() { return mGeneration; } 1.73 + 1.74 +#ifdef MOZ_TASK_TRACER 1.75 + void DispatchTracedTask() 1.76 + { 1.77 + mTracedTask = mozilla::tasktracer::CreateFakeTracedTask(*(int**)(this)); 1.78 + } 1.79 +#endif 1.80 + 1.81 +private: 1.82 + ~nsTimerImpl(); 1.83 + nsresult InitCommon(uint32_t aType, uint32_t aDelay); 1.84 + 1.85 + void ReleaseCallback() 1.86 + { 1.87 + // if we're the last owner of the callback object, make 1.88 + // sure that we don't recurse into ReleaseCallback in case 1.89 + // the callback's destructor calls Cancel() or similar. 1.90 + uint8_t cbType = mCallbackType; 1.91 + mCallbackType = CALLBACK_TYPE_UNKNOWN; 1.92 + 1.93 + if (cbType == CALLBACK_TYPE_INTERFACE) 1.94 + NS_RELEASE(mCallback.i); 1.95 + else if (cbType == CALLBACK_TYPE_OBSERVER) 1.96 + NS_RELEASE(mCallback.o); 1.97 + } 1.98 + 1.99 + bool IsRepeating() const { 1.100 + PR_STATIC_ASSERT(TYPE_ONE_SHOT < TYPE_REPEATING_SLACK); 1.101 + PR_STATIC_ASSERT(TYPE_REPEATING_SLACK < TYPE_REPEATING_PRECISE); 1.102 + PR_STATIC_ASSERT(TYPE_REPEATING_PRECISE < TYPE_REPEATING_PRECISE_CAN_SKIP); 1.103 + return mType >= TYPE_REPEATING_SLACK; 1.104 + } 1.105 + 1.106 + bool IsRepeatingPrecisely() const { 1.107 + return mType >= TYPE_REPEATING_PRECISE; 1.108 + } 1.109 + 1.110 + nsCOMPtr<nsIEventTarget> mEventTarget; 1.111 + 1.112 + void * mClosure; 1.113 + 1.114 + union CallbackUnion { 1.115 + nsTimerCallbackFunc c; 1.116 + nsITimerCallback * i; 1.117 + nsIObserver * o; 1.118 + } mCallback; 1.119 + 1.120 + // Some callers expect to be able to access the callback while the 1.121 + // timer is firing. 1.122 + nsCOMPtr<nsITimerCallback> mTimerCallbackWhileFiring; 1.123 + 1.124 + // These members are set by Init (called from NS_NewTimer) and never reset. 1.125 + uint8_t mCallbackType; 1.126 + 1.127 + // These members are set by the initiating thread, when the timer's type is 1.128 + // changed and during the period where it fires on that thread. 1.129 + uint8_t mType; 1.130 + bool mFiring; 1.131 + 1.132 + 1.133 + // Use a bool (int) here to isolate loads and stores of these two members 1.134 + // done on various threads under the protection of TimerThread::mLock, from 1.135 + // loads and stores done on the initiating/type-changing/timer-firing thread 1.136 + // to the above uint8_t/bool members. 1.137 + bool mArmed; 1.138 + bool mCanceled; 1.139 + 1.140 + // The generation number of this timer, re-generated each time the timer is 1.141 + // initialized so one-shot timers can be canceled and re-initialized by the 1.142 + // arming thread without any bad race conditions. 1.143 + int32_t mGeneration; 1.144 + 1.145 + uint32_t mDelay; 1.146 + TimeStamp mTimeout; 1.147 + 1.148 +#ifdef MOZ_TASK_TRACER 1.149 + nsAutoPtr<mozilla::tasktracer::FakeTracedTask> mTracedTask; 1.150 +#endif 1.151 + 1.152 +#ifdef DEBUG_TIMERS 1.153 + TimeStamp mStart, mStart2; 1.154 + static double sDeltaSum; 1.155 + static double sDeltaSumSquared; 1.156 + static double sDeltaNum; 1.157 +#endif 1.158 + 1.159 +}; 1.160 + 1.161 +#endif /* nsTimerImpl_h___ */