summaryrefslogtreecommitdiffstats
path: root/xpcom/threads/nsTimerImpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'xpcom/threads/nsTimerImpl.h')
-rw-r--r--xpcom/threads/nsTimerImpl.h53
1 files changed, 39 insertions, 14 deletions
diff --git a/xpcom/threads/nsTimerImpl.h b/xpcom/threads/nsTimerImpl.h
index 298f862..91e8952 100644
--- a/xpcom/threads/nsTimerImpl.h
+++ b/xpcom/threads/nsTimerImpl.h
@@ -67,15 +67,49 @@ class nsTimerImpl {
mCallback.c = nullptr;
}
- Callback(const Callback& other) = delete;
- Callback& operator=(const Callback& other) = delete;
+ Callback(const Callback& other) : Callback() { *this = other; }
- ~Callback() {
+ enum class Type : uint8_t {
+ Unknown = 0,
+ Interface = 1,
+ Function = 2,
+ Observer = 3,
+ };
+
+ Callback& operator=(const Callback& other) {
+ if (this != &other) {
+ clear();
+ mType = other.mType;
+ switch (mType) {
+ case Type::Unknown:
+ break;
+ case Type::Interface:
+ mCallback.i = other.mCallback.i;
+ NS_ADDREF(mCallback.i);
+ break;
+ case Type::Function:
+ mCallback.c = other.mCallback.c;
+ break;
+ case Type::Observer:
+ mCallback.o = other.mCallback.o;
+ NS_ADDREF(mCallback.o);
+ break;
+ }
+ mName = other.mName;
+ mClosure = other.mClosure;
+ }
+ return *this;
+ }
+
+ ~Callback() { clear(); }
+
+ void clear() {
if (mType == Type::Interface) {
NS_RELEASE(mCallback.i);
} else if (mType == Type::Observer) {
NS_RELEASE(mCallback.o);
}
+ mType = Type::Unknown;
}
void swap(Callback& other) {
@@ -85,12 +119,6 @@ class nsTimerImpl {
std::swap(mClosure, other.mClosure);
}
- enum class Type : uint8_t {
- Unknown = 0,
- Interface = 1,
- Function = 2,
- Observer = 3,
- };
Type mType;
union CallbackUnion {
@@ -123,10 +151,6 @@ class nsTimerImpl {
Callback& GetCallback() {
mMutex.AssertCurrentThreadOwns();
- if (mCallback.mType == Callback::Type::Unknown) {
- return mCallbackDuringFire;
- }
-
return mCallback;
}
@@ -193,7 +217,8 @@ class nsTimerImpl {
RefPtr<nsITimer> mITimer;
mozilla::Mutex mMutex;
Callback mCallback;
- Callback mCallbackDuringFire;
+ // Counter because in rare cases we can Fire reentrantly
+ unsigned int mFiring;
};
class nsTimer final : public nsITimer {