зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1465452 Part 2 - Allow nsISupports subclasses to record/replay their refcount changes, r=froydnj.
--HG-- extra : rebase_source : c67e1da8a34c6b6bf6e40087da85c599f2aaeaf9
This commit is contained in:
Родитель
38e406e8a5
Коммит
b65c22bb28
|
@ -22,6 +22,7 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
|
#include "mozilla/Atomics.h"
|
||||||
#include "mozilla/Compiler.h"
|
#include "mozilla/Compiler.h"
|
||||||
#include "mozilla/Likely.h"
|
#include "mozilla/Likely.h"
|
||||||
#include "mozilla/MacroArgs.h"
|
#include "mozilla/MacroArgs.h"
|
||||||
|
@ -317,14 +318,15 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class ThreadSafeAutoRefCnt
|
template <recordreplay::Behavior Recording>
|
||||||
|
class ThreadSafeAutoRefCntWithRecording
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ThreadSafeAutoRefCnt() : mValue(0) {}
|
ThreadSafeAutoRefCntWithRecording() : mValue(0) {}
|
||||||
explicit ThreadSafeAutoRefCnt(nsrefcnt aValue) : mValue(aValue) {}
|
explicit ThreadSafeAutoRefCntWithRecording(nsrefcnt aValue) : mValue(aValue) {}
|
||||||
|
|
||||||
ThreadSafeAutoRefCnt(const ThreadSafeAutoRefCnt&) = delete;
|
ThreadSafeAutoRefCntWithRecording(const ThreadSafeAutoRefCntWithRecording&) = delete;
|
||||||
void operator=(const ThreadSafeAutoRefCnt&) = delete;
|
void operator=(const ThreadSafeAutoRefCntWithRecording&) = delete;
|
||||||
|
|
||||||
// only support prefix increment/decrement
|
// only support prefix increment/decrement
|
||||||
MOZ_ALWAYS_INLINE nsrefcnt operator++()
|
MOZ_ALWAYS_INLINE nsrefcnt operator++()
|
||||||
|
@ -337,6 +339,7 @@ public:
|
||||||
// first increment on that thread. The necessary memory
|
// first increment on that thread. The necessary memory
|
||||||
// synchronization is done by the mechanism that transfers the
|
// synchronization is done by the mechanism that transfers the
|
||||||
// pointer between threads.
|
// pointer between threads.
|
||||||
|
detail::AutoRecordAtomicAccess<Recording> record;
|
||||||
return mValue.fetch_add(1, std::memory_order_relaxed) + 1;
|
return mValue.fetch_add(1, std::memory_order_relaxed) + 1;
|
||||||
}
|
}
|
||||||
MOZ_ALWAYS_INLINE nsrefcnt operator--()
|
MOZ_ALWAYS_INLINE nsrefcnt operator--()
|
||||||
|
@ -345,6 +348,7 @@ public:
|
||||||
// release semantics so that prior writes on this thread are visible
|
// release semantics so that prior writes on this thread are visible
|
||||||
// to the thread that destroys the object when it reads mValue with
|
// to the thread that destroys the object when it reads mValue with
|
||||||
// acquire semantics.
|
// acquire semantics.
|
||||||
|
detail::AutoRecordAtomicAccess<Recording> record;
|
||||||
nsrefcnt result = mValue.fetch_sub(1, std::memory_order_release) - 1;
|
nsrefcnt result = mValue.fetch_sub(1, std::memory_order_release) - 1;
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
// We're going to destroy the object on this thread, so we need
|
// We're going to destroy the object on this thread, so we need
|
||||||
|
@ -360,6 +364,7 @@ public:
|
||||||
{
|
{
|
||||||
// Use release semantics since we're not sure what the caller is
|
// Use release semantics since we're not sure what the caller is
|
||||||
// doing.
|
// doing.
|
||||||
|
detail::AutoRecordAtomicAccess<Recording> record;
|
||||||
mValue.store(aValue, std::memory_order_release);
|
mValue.store(aValue, std::memory_order_release);
|
||||||
return aValue;
|
return aValue;
|
||||||
}
|
}
|
||||||
|
@ -368,6 +373,7 @@ public:
|
||||||
{
|
{
|
||||||
// Use acquire semantics since we're not sure what the caller is
|
// Use acquire semantics since we're not sure what the caller is
|
||||||
// doing.
|
// doing.
|
||||||
|
detail::AutoRecordAtomicAccess<Recording> record;
|
||||||
return mValue.load(std::memory_order_acquire);
|
return mValue.load(std::memory_order_acquire);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,6 +383,10 @@ private:
|
||||||
nsrefcnt operator--(int) = delete;
|
nsrefcnt operator--(int) = delete;
|
||||||
std::atomic<nsrefcnt> mValue;
|
std::atomic<nsrefcnt> mValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef ThreadSafeAutoRefCntWithRecording<recordreplay::Behavior::DontPreserve>
|
||||||
|
ThreadSafeAutoRefCnt;
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -398,7 +408,7 @@ protected: \
|
||||||
NS_DECL_OWNINGTHREAD \
|
NS_DECL_OWNINGTHREAD \
|
||||||
public:
|
public:
|
||||||
|
|
||||||
#define NS_DECL_THREADSAFE_ISUPPORTS \
|
#define NS_DECL_THREADSAFE_ISUPPORTS_WITH_RECORDING(_recording) \
|
||||||
public: \
|
public: \
|
||||||
NS_IMETHOD QueryInterface(REFNSIID aIID, \
|
NS_IMETHOD QueryInterface(REFNSIID aIID, \
|
||||||
void** aInstancePtr) override; \
|
void** aInstancePtr) override; \
|
||||||
|
@ -406,10 +416,13 @@ public: \
|
||||||
NS_IMETHOD_(MozExternalRefCountType) Release(void) override; \
|
NS_IMETHOD_(MozExternalRefCountType) Release(void) override; \
|
||||||
typedef mozilla::TrueType HasThreadSafeRefCnt; \
|
typedef mozilla::TrueType HasThreadSafeRefCnt; \
|
||||||
protected: \
|
protected: \
|
||||||
::mozilla::ThreadSafeAutoRefCnt mRefCnt; \
|
::mozilla::ThreadSafeAutoRefCntWithRecording<_recording> mRefCnt; \
|
||||||
NS_DECL_OWNINGTHREAD \
|
NS_DECL_OWNINGTHREAD \
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
#define NS_DECL_THREADSAFE_ISUPPORTS \
|
||||||
|
NS_DECL_THREADSAFE_ISUPPORTS_WITH_RECORDING(mozilla::recordreplay::Behavior::DontPreserve)
|
||||||
|
|
||||||
#define NS_DECL_CYCLE_COLLECTING_ISUPPORTS \
|
#define NS_DECL_CYCLE_COLLECTING_ISUPPORTS \
|
||||||
public: \
|
public: \
|
||||||
NS_IMETHOD QueryInterface(REFNSIID aIID, \
|
NS_IMETHOD QueryInterface(REFNSIID aIID, \
|
||||||
|
|
Загрузка…
Ссылка в новой задаче