Skip to content

Commit

Permalink
Bug 953435 - Browser hang on Mac if an AfterProcessNextEvent callback…
Browse files Browse the repository at this point in the history
… tries to spin the event loop, r=nfroyd+smichaud

--HG--
extra : rebase_source : e999d852f5f73b18f37ff6a5488cc171c95d9e61
  • Loading branch information
Olli Pettay authored and Olli Pettay committed Jan 8, 2014
1 parent 8ca53ac commit 5cdea8d
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 9 deletions.
1 change: 0 additions & 1 deletion widget/cocoa/nsAppShell.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ class nsAppShell : public nsBaseAppShell
// to 3%-4%). See bmo bug 395397.
static const uint32_t kHadMoreEventsCountMax = 3;

int32_t mRecursionDepth;
int32_t mNativeEventCallbackDepth;
// Can be set from different threads, so must be modified atomically
int32_t mNativeEventScheduledDepth;
Expand Down
12 changes: 5 additions & 7 deletions widget/cocoa/nsAppShell.mm
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ - (void)beginMenuTracking:(NSNotification*)aNotification;
, mTerminated(false)
, mSkippedNativeCallback(false)
, mHadMoreEventsCount(0)
, mRecursionDepth(0)
, mNativeEventCallbackDepth(0)
, mNativeEventScheduledDepth(0)
{
Expand Down Expand Up @@ -712,11 +711,14 @@ - (void)beginMenuTracking:(NSNotification*)aNotification;
bool
nsAppShell::InGeckoMainEventLoop()
{
if ((gXULModalLevel > 0) || (mRecursionDepth > 0))
if (gXULModalLevel > 0)
return false;
if (mNativeEventCallbackDepth <= 0)
return false;
return true;

bool isProcessingEvents = false;
NS_GetCurrentThread()->GetIsProcessingEvents(&isProcessingEvents);
return !isProcessingEvents;
}

// Run
Expand Down Expand Up @@ -818,8 +820,6 @@ - (void)beginMenuTracking:(NSNotification*)aNotification;
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;

mRecursionDepth = aRecursionDepth;

NS_ASSERTION(mAutoreleasePools,
"No stack on which to store autorelease pool");

Expand All @@ -845,8 +845,6 @@ - (void)beginMenuTracking:(NSNotification*)aNotification;
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;

mRecursionDepth = aRecursionDepth;

CFIndex count = ::CFArrayGetCount(mAutoreleasePools);

NS_ASSERTION(mAutoreleasePools && count,
Expand Down
11 changes: 11 additions & 0 deletions xpcom/threads/LazyIdleThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,17 @@ LazyIdleThread::ProcessNextEvent(bool aMayWait,
return NS_ERROR_UNEXPECTED;
}

NS_IMETHODIMP
LazyIdleThread::GetIsProcessingEvents(bool* aIsProcessing)
{
if (mThread) {
return mThread->GetIsProcessingEvents(aIsProcessing);
}

*aIsProcessing = false;
return NS_OK;
}

NS_IMETHODIMP
LazyIdleThread::Notify(nsITimer* aTimer)
{
Expand Down
8 changes: 7 additions & 1 deletion xpcom/threads/nsIThread.idl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*
* See nsIThreadManager for the API used to create and locate threads.
*/
[scriptable, uuid(9c889946-a73a-4af3-ae9a-ea64f7d4e3ca)]
[scriptable, uuid(4df07d3a-e759-4256-ba4e-7e2265354ec3)]
interface nsIThread : nsIEventTarget
{
/**
Expand Down Expand Up @@ -82,4 +82,10 @@ interface nsIThread : nsIEventTarget
* not the current thread.
*/
boolean processNextEvent(in boolean mayWait);

/**
* true if we're processing runnables or thread observers and if this is the
* current thread.
*/
readonly attribute boolean isProcessingEvents;
};
16 changes: 16 additions & 0 deletions xpcom/threads/nsThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ nsThread::nsThread(MainThreadFlag aMainThread, uint32_t aStackSize)
, mThread(nullptr)
, mRunningEvent(0)
, mStackSize(aStackSize)
, mProcessingEvent(0)
, mShutdownContext(nullptr)
, mShutdownRequired(false)
, mEventsAreDoomed(false)
Expand Down Expand Up @@ -596,6 +597,8 @@ nsThread::ProcessNextEvent(bool mayWait, bool *result)
}
}

++mProcessingEvent;

bool notifyMainThreadObserver =
(MAIN_THREAD == mIsMainThread) && sMainThreadObserver;
if (notifyMainThreadObserver)
Expand Down Expand Up @@ -650,9 +653,22 @@ nsThread::ProcessNextEvent(bool mayWait, bool *result)
if (notifyMainThreadObserver && sMainThreadObserver)
sMainThreadObserver->AfterProcessNextEvent(this, mRunningEvent, *result);

--mProcessingEvent;

return rv;
}

NS_IMETHODIMP
nsThread::GetIsProcessingEvents(bool* aIsProcessing)
{
if (NS_WARN_IF(PR_GetCurrentThread() != mThread)) {
return NS_ERROR_NOT_SAME_THREAD;
}

*aIsProcessing = mProcessingEvent != 0;
return NS_OK;
}

//-----------------------------------------------------------------------------
// nsISupportsPriority

Expand Down
2 changes: 2 additions & 0 deletions xpcom/threads/nsThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ class nsThread : public nsIThreadInternal,
uint32_t mRunningEvent; // counter
uint32_t mStackSize;

uint32_t mProcessingEvent;

struct nsThreadShutdownContext *mShutdownContext;

bool mShutdownRequired;
Expand Down

0 comments on commit 5cdea8d

Please sign in to comment.