summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPale Moon <git-repo@palemoon.org>2018-01-28 11:15:05 +0100
committerPale Moon <git-repo@palemoon.org>2018-01-28 11:15:05 +0100
commit961d0396788462446a5e49504afdd2e259f97227 (patch)
tree129e944faabcb3bad9a98551b741281bc57e86e0
parentac44e1feee544e54b9cf625a38789782b76f7900 (diff)
downloadpalemoon-gre-961d0396788462446a5e49504afdd2e259f97227.tar.gz
Avoid a race condition in AutoClose.
-rw-r--r--netwerk/base/AutoClose.h43
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