mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-07 18:04:46 +00:00
Bug 1392235, part 2 - Fix AutoReferenceChainGuard to never set/unset state when it breaks a reference chain. r=longsonr
MozReview-Commit-ID: I4y8eNGU0Er
This commit is contained in:
parent
37ee4415b8
commit
45e8436173
@ -82,22 +82,23 @@ public:
|
|||||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||||
: mFrame(aFrame)
|
: mFrame(aFrame)
|
||||||
, mFrameInUse(aFrameInUse)
|
, mFrameInUse(aFrameInUse)
|
||||||
|
, mChainCounter(aChainCounter)
|
||||||
, mMaxChainLength(aMaxChainLength)
|
, mMaxChainLength(aMaxChainLength)
|
||||||
|
, mBrokeReference(false)
|
||||||
{
|
{
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||||
MOZ_ASSERT(aFrame && aFrameInUse && aChainCounter);
|
MOZ_ASSERT(aFrame && aFrameInUse && aChainCounter);
|
||||||
MOZ_ASSERT(aMaxChainLength > 0);
|
MOZ_ASSERT(aMaxChainLength > 0);
|
||||||
MOZ_ASSERT(*aChainCounter == noChain ||
|
MOZ_ASSERT(*aChainCounter == noChain ||
|
||||||
(*aChainCounter >= 0 && *aChainCounter < aMaxChainLength));
|
(*aChainCounter >= 0 && *aChainCounter < aMaxChainLength));
|
||||||
|
|
||||||
if (*aChainCounter == noChain) {
|
|
||||||
// Initialize - we start at aMaxChainLength and decrement towards zero.
|
|
||||||
*aChainCounter = aMaxChainLength;
|
|
||||||
}
|
|
||||||
mChainCounter = aChainCounter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~AutoReferenceChainGuard() {
|
~AutoReferenceChainGuard() {
|
||||||
|
if (mBrokeReference) {
|
||||||
|
// We didn't change mFrameInUse or mChainCounter
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
*mFrameInUse = false;
|
*mFrameInUse = false;
|
||||||
|
|
||||||
// If we fail this assert then there were more destructor calls than
|
// If we fail this assert then there were more destructor calls than
|
||||||
@ -121,22 +122,30 @@ public:
|
|||||||
*/
|
*/
|
||||||
MOZ_MUST_USE bool Reference() {
|
MOZ_MUST_USE bool Reference() {
|
||||||
if (MOZ_UNLIKELY(*mFrameInUse)) {
|
if (MOZ_UNLIKELY(*mFrameInUse)) {
|
||||||
|
mBrokeReference = true;
|
||||||
ReportErrorToConsole();
|
ReportErrorToConsole();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*mChainCounter == noChain) {
|
||||||
|
// Initialize - we start at aMaxChainLength and decrement towards zero.
|
||||||
|
*mChainCounter = mMaxChainLength;
|
||||||
|
} else {
|
||||||
|
// If we fail this assertion then either a consumer failed to break a
|
||||||
|
// reference loop/chain, or else they called Reference() more than once
|
||||||
|
MOZ_ASSERT(*mChainCounter >= 0);
|
||||||
|
|
||||||
|
if (MOZ_UNLIKELY(*mChainCounter < 1)) {
|
||||||
|
mBrokeReference = true;
|
||||||
|
ReportErrorToConsole();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We only set these once we know we're returing true.
|
||||||
*mFrameInUse = true;
|
*mFrameInUse = true;
|
||||||
|
|
||||||
// If we fail this assertion then either a consumer failed to break a
|
|
||||||
// reference loop/chain, or else they called Reference() more than once
|
|
||||||
MOZ_ASSERT(*mChainCounter >= 0);
|
|
||||||
|
|
||||||
(*mChainCounter)--;
|
(*mChainCounter)--;
|
||||||
|
|
||||||
if (MOZ_UNLIKELY(*mChainCounter < 0)) {
|
|
||||||
ReportErrorToConsole();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,6 +166,7 @@ private:
|
|||||||
bool* mFrameInUse;
|
bool* mFrameInUse;
|
||||||
int16_t* mChainCounter;
|
int16_t* mChainCounter;
|
||||||
const int16_t mMaxChainLength;
|
const int16_t mMaxChainLength;
|
||||||
|
bool mBrokeReference;
|
||||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user