Bug 1157488 - Assert against re-entrant sync sections. r=bent
authorBobby Holley <bobbyholley@gmail.com>
Wed, 22 Apr 2015 15:32:43 -0700
changeset 240669 7cd7611ed7b32d22b179a4baa97bdbc0263370b4
parent 240668 e436e20e5f2c52fa6b2322f6a5d2f9ee902ebb22
child 240670 3ea11ef5c0fba0c42ee0c3851cd0ead05c6fb04a
push id28640
push usercbook@mozilla.com
push dateThu, 23 Apr 2015 13:41:18 +0000
treeherdermozilla-central@60a3e492f46e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent
bugs1157488
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1157488 - Assert against re-entrant sync sections. r=bent
widget/nsBaseAppShell.cpp
widget/nsBaseAppShell.h
--- a/widget/nsBaseAppShell.cpp
+++ b/widget/nsBaseAppShell.cpp
@@ -26,16 +26,17 @@ nsBaseAppShell::nsBaseAppShell()
   , mEventloopNestingLevel(0)
   , mBlockedWait(nullptr)
   , mFavorPerf(0)
   , mNativeEventPending(false)
   , mStarvationDelay(0)
   , mSwitchTime(0)
   , mLastNativeEventTime(0)
   , mEventloopNestingState(eEventloopNone)
+  , mRunningSyncSections(false)
   , mRunning(false)
   , mExiting(false)
   , mBlockNativeEvent(false)
 {
 }
 
 nsBaseAppShell::~nsBaseAppShell()
 {
@@ -345,16 +346,21 @@ nsBaseAppShell::DecrementEventloopNestin
 
 void
 nsBaseAppShell::RunSyncSectionsInternal(bool aStable,
                                         uint32_t aThreadRecursionLevel)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!mSyncSections.IsEmpty(), "Nothing to do!");
 
+  // We don't support re-entering sync sections. This effectively means that
+  // sync sections may not spin the event loop.
+  MOZ_RELEASE_ASSERT(!mRunningSyncSections);
+  mRunningSyncSections = true;
+
   // We've got synchronous sections. Run all of them that are are awaiting a
   // stable state if aStable is true (i.e. we really are in a stable state).
   // Also run the synchronous sections that are simply waiting for the right
   // combination of event loop nesting level and thread recursion level.
   // Note that a synchronous section could add another synchronous section, so
   // we don't remove elements from mSyncSections until all sections have been
   // run, or else we'll screw up our iteration. Any sync sections that are not
   // ready to be run are saved for later.
@@ -372,16 +378,17 @@ nsBaseAppShell::RunSyncSectionsInternal(
     else {
       // Add to pending list.
       SyncSection* pending = pendingSyncSections.AppendElement();
       section.Forget(pending);
     }
   }
 
   mSyncSections.SwapElements(pendingSyncSections);
+  mRunningSyncSections = false;
 }
 
 void
 nsBaseAppShell::ScheduleSyncSection(nsIRunnable* aRunnable, bool aStable)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
 
   nsIThread* thread = NS_GetCurrentThread();
--- a/widget/nsBaseAppShell.h
+++ b/widget/nsBaseAppShell.h
@@ -129,16 +129,17 @@ private:
   PRIntervalTime mLastNativeEventTime;
   enum EventloopNestingState {
     eEventloopNone,  // top level thread execution
     eEventloopXPCOM, // innermost native event loop is ProcessNextNativeEvent
     eEventloopOther  // innermost native event loop is a native library/plugin etc
   };
   EventloopNestingState mEventloopNestingState;
   nsTArray<SyncSection> mSyncSections;
+  bool mRunningSyncSections;
   bool mRunning;
   bool mExiting;
   /**
    * mBlockNativeEvent blocks the appshell from processing native events.
    * It is set to true while a nested native event loop (eEventloopOther)
    * is processing gecko events in NativeEventCallback(), thus queuing up
    * native events until we return to that loop (bug 420148).
    * We force mBlockNativeEvent to false in case handling one of the gecko