diff options
author | Pale Moon <git-repo@palemoon.org> | 2018-01-28 11:15:05 +0100 |
---|---|---|
committer | Pale Moon <git-repo@palemoon.org> | 2018-01-28 11:15:05 +0100 |
commit | 961d0396788462446a5e49504afdd2e259f97227 (patch) | |
tree | 129e944faabcb3bad9a98551b741281bc57e86e0 | |
parent | ac44e1feee544e54b9cf625a38789782b76f7900 (diff) | |
download | palemoon-gre-961d0396788462446a5e49504afdd2e259f97227.tar.gz |
Avoid a race condition in AutoClose.
-rw-r--r-- | netwerk/base/AutoClose.h | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/netwerk/base/AutoClose.h b/netwerk/base/AutoClose.h index ba82614f6..e26960e84 100644 --- a/netwerk/base/AutoClose.h +++ b/netwerk/base/AutoClose.h @@ -8,6 +8,7 @@ #define mozilla_net_AutoClose_h #include "nsCOMPtr.h" +#include "mozilla/Mutex.h" namespace mozilla { namespace net { @@ -18,49 +19,48 @@ template <typename T> class AutoClose { public: - AutoClose() { } + AutoClose() : mMutex("net::AutoClose.mMutex") { } ~AutoClose(){ - Close(); + CloseAndRelease(); } - operator bool() const + operator bool() { + MutexAutoLock lock(mMutex); return mPtr; } already_AddRefed<T> forget() { + MutexAutoLock lock(mMutex); return mPtr.forget(); } void takeOver(nsCOMPtr<T> & rhs) { - Close(); - mPtr = rhs.forget(); - } - - void takeOver(AutoClose<T> & rhs) - { - Close(); - mPtr = rhs.mPtr.forget(); + already_AddRefed<T> other = rhs.forget(); + TakeOverInternal(&other); } void CloseAndRelease() { - Close(); - mPtr = nullptr; - } - - T* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN - { - return mPtr.operator->(); + TakeOverInternal(nullptr); } private: - void Close() + void TakeOverInternal(already_AddRefed<T> *aOther) { - if (mPtr) { - mPtr->Close(); + nsCOMPtr<T> ptr; + { + MutexAutoLock lock(mMutex); + ptr.swap(mPtr); + if (aOther) { + mPtr = *aOther; + } + } + + if (ptr) { + ptr->Close(); } } @@ -68,6 +68,7 @@ private: AutoClose(const AutoClose<T> &) = delete; nsCOMPtr<T> mPtr; + Mutex mMutex; }; } } // namespace mozilla::net |