зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1221160 - fix AutoTraceLogLock deadlock on Windows; r=froydnj
From e3a1e57c0c8be8214a12e31c6e4950a676efd9bc Mon Sep 17 00:00:00 2001 MozReview-Commit-ID: JrPiE7eixpy --HG-- extra : rebase_source : 7f322a0c95c46c0bd1721f982fab8ab421866d70 extra : source : 883ed100b755b9a528104a62ed631beaff6c8cf2
This commit is contained in:
Родитель
6a82950698
Коммит
a54ea93315
|
@ -61,17 +61,24 @@
|
|||
// only held for a very short time, and gets grabbed at a very high frequency
|
||||
// (~100000 times per second). On Mac, the overhead of using a regular lock
|
||||
// is very high, see bug 1137963.
|
||||
static mozilla::Atomic<bool, mozilla::ReleaseAcquire> gTraceLogLocked;
|
||||
static mozilla::Atomic<uintptr_t, mozilla::ReleaseAcquire> gTraceLogLocked;
|
||||
|
||||
struct MOZ_STACK_CLASS AutoTraceLogLock final
|
||||
{
|
||||
bool doRelease;
|
||||
AutoTraceLogLock()
|
||||
: doRelease(true)
|
||||
{
|
||||
while (!gTraceLogLocked.compareExchange(false, true)) {
|
||||
PR_Sleep(PR_INTERVAL_NO_WAIT); /* yield */
|
||||
uintptr_t currentThread = reinterpret_cast<uintptr_t>(PR_GetCurrentThread());
|
||||
if (gTraceLogLocked == currentThread) {
|
||||
doRelease = false;
|
||||
} else {
|
||||
while (!gTraceLogLocked.compareExchange(0, currentThread)) {
|
||||
PR_Sleep(PR_INTERVAL_NO_WAIT); /* yield */
|
||||
}
|
||||
}
|
||||
}
|
||||
~AutoTraceLogLock() { gTraceLogLocked = false; }
|
||||
~AutoTraceLogLock() { if (doRelease) gTraceLogLocked = 0; }
|
||||
};
|
||||
|
||||
static PLHashTable* gBloatView;
|
||||
|
@ -1119,14 +1126,14 @@ NS_LogAddRef(void* aPtr, nsrefcnt aRefcnt,
|
|||
|
||||
bool loggingThisObject = (!gObjectsToLog || LogThisObj(serialno));
|
||||
if (aRefcnt == 1 && gAllocLog && loggingThisType && loggingThisObject) {
|
||||
fprintf(gAllocLog, "\n<%s> %p %" PRIdPTR " Create\n", aClass, aPtr, serialno);
|
||||
fprintf(gAllocLog, "\n<%s> %p %" PRIdPTR " Create [thread %p]\n", aClass, aPtr, serialno, PR_GetCurrentThread());
|
||||
nsTraceRefcnt::WalkTheStackCached(gAllocLog);
|
||||
}
|
||||
|
||||
if (gRefcntsLog && loggingThisType && loggingThisObject) {
|
||||
// Can't use MOZ_LOG(), b/c it truncates the line
|
||||
fprintf(gRefcntsLog, "\n<%s> %p %" PRIuPTR " AddRef %" PRIuPTR "\n",
|
||||
aClass, aPtr, serialno, aRefcnt);
|
||||
fprintf(gRefcntsLog, "\n<%s> %p %" PRIuPTR " AddRef %" PRIuPTR " [thread %p]\n",
|
||||
aClass, aPtr, serialno, aRefcnt, PR_GetCurrentThread());
|
||||
nsTraceRefcnt::WalkTheStackCached(gRefcntsLog);
|
||||
fflush(gRefcntsLog);
|
||||
}
|
||||
|
@ -1173,8 +1180,8 @@ NS_LogRelease(void* aPtr, nsrefcnt aRefcnt, const char* aClass)
|
|||
if (gRefcntsLog && loggingThisType && loggingThisObject) {
|
||||
// Can't use MOZ_LOG(), b/c it truncates the line
|
||||
fprintf(gRefcntsLog,
|
||||
"\n<%s> %p %" PRIuPTR " Release %" PRIuPTR "\n",
|
||||
aClass, aPtr, serialno, aRefcnt);
|
||||
"\n<%s> %p %" PRIuPTR " Release %" PRIuPTR " [thread %p]\n",
|
||||
aClass, aPtr, serialno, aRefcnt, PR_GetCurrentThread());
|
||||
nsTraceRefcnt::WalkTheStackCached(gRefcntsLog);
|
||||
fflush(gRefcntsLog);
|
||||
}
|
||||
|
@ -1183,7 +1190,7 @@ NS_LogRelease(void* aPtr, nsrefcnt aRefcnt, const char* aClass)
|
|||
// yet we still want to see deletion information:
|
||||
|
||||
if (aRefcnt == 0 && gAllocLog && loggingThisType && loggingThisObject) {
|
||||
fprintf(gAllocLog, "\n<%s> %p %" PRIdPTR " Destroy\n", aClass, aPtr, serialno);
|
||||
fprintf(gAllocLog, "\n<%s> %p %" PRIdPTR " Destroy [thread %p]\n", aClass, aPtr, serialno, PR_GetCurrentThread());
|
||||
nsTraceRefcnt::WalkTheStackCached(gAllocLog);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче