Bug 939182 - Add 'eventWasProcessed' argument to nsIThreadObserver::afterProcessNextEvent(), r=bsmedberg.
authorBen Turner <bent.mozilla@gmail.com>
Wed, 23 Oct 2013 05:01:20 -0700
changeset 176853 1d2659a098c28049976213050c0083c65d0d175e
parent 176852 475f1db6b9107f05e861998f7a1f26f9f9042660
child 176854 fa74710fdeefbd146f716a5a432344f82d928a81
push id462
push userraliiev@mozilla.com
push dateTue, 22 Apr 2014 00:22:30 +0000
treeherdermozilla-release@ac5db8c74ac0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs939182
milestone29.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 939182 - Add 'eventWasProcessed' argument to nsIThreadObserver::afterProcessNextEvent(), r=bsmedberg.
dom/ipc/ContentParent.cpp
js/xpconnect/src/nsXPConnect.cpp
layout/style/Loader.cpp
netwerk/base/src/nsSocketTransportService2.cpp
netwerk/cache2/CacheIOThread.cpp
widget/cocoa/nsAppShell.h
widget/cocoa/nsAppShell.mm
widget/xpwidgets/nsBaseAppShell.cpp
xpcom/threads/LazyIdleThread.cpp
xpcom/threads/nsIThreadInternal.idl
xpcom/threads/nsThread.cpp
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -2719,17 +2719,18 @@ ContentParent::OnProcessNextEvent(nsIThr
                                   uint32_t recursionDepth)
 {
     return NS_OK;
 }
 
 /* void afterProcessNextEvent (in nsIThreadInternal thread, in unsigned long recursionDepth); */
 NS_IMETHODIMP
 ContentParent::AfterProcessNextEvent(nsIThreadInternal *thread,
-                                     uint32_t recursionDepth)
+                                     uint32_t recursionDepth,
+                                     bool eventWasProcessed)
 {
     return NS_OK;
 }
 
 bool
 ContentParent::RecvShowAlertNotification(const nsString& aImageUrl, const nsString& aTitle,
                                          const nsString& aText, const bool& aTextClickable,
                                          const nsString& aCookie, const nsString& aName,
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -1115,17 +1115,18 @@ nsXPConnect::OnProcessNextEvent(nsIThrea
     MOZ_ASSERT(NS_IsMainThread());
     bool ok = PushJSContextNoScriptContext(nullptr);
     NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPConnect::AfterProcessNextEvent(nsIThreadInternal *aThread,
-                                   uint32_t aRecursionDepth)
+                                   uint32_t aRecursionDepth,
+                                   bool aEventWasProcessed)
 {
     // Watch out for unpaired events during observer registration.
     if (MOZ_UNLIKELY(mEventDepth == 0))
         return NS_OK;
     mEventDepth--;
 
     // Now that we're back to the event loop, reset the slow script checkpoint.
     mRuntime->OnAfterProcessNextEvent();
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -444,17 +444,18 @@ SheetLoadData::OnProcessNextEvent(nsIThr
   // We want to fire our load even before or after event processing,
   // whichever comes first.
   FireLoadEvent(aThread);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 SheetLoadData::AfterProcessNextEvent(nsIThreadInternal* aThread,
-                                     uint32_t aRecursionDepth)
+                                     uint32_t aRecursionDepth,
+                                     bool aEventWasProcessed)
 {
   // We want to fire our load even before or after event processing,
   // whichever comes first.
   FireLoadEvent(aThread);
   return NS_OK;
 }
 
 void
--- a/netwerk/base/src/nsSocketTransportService2.cpp
+++ b/netwerk/base/src/nsSocketTransportService2.cpp
@@ -626,17 +626,18 @@ NS_IMETHODIMP
 nsSocketTransportService::OnProcessNextEvent(nsIThreadInternal *thread,
                                              bool mayWait, uint32_t depth)
 {
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSocketTransportService::AfterProcessNextEvent(nsIThreadInternal* thread,
-                                                uint32_t depth)
+                                                uint32_t depth,
+                                                bool eventWasProcessed)
 {
     return NS_OK;
 }
 
 #ifdef MOZ_NUWA_PROCESS
 #include "ipc/Nuwa.h"
 #endif
 
@@ -1123,10 +1124,8 @@ void
 nsSocketTransportService::GetSocketConnections(nsTArray<SocketInfo> *data)
 {
     NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
     for (uint32_t i = 0; i < mActiveCount; i++)
         AnalyzeConnection(data, &mActiveList[i], true);
     for (uint32_t i = 0; i < mIdleCount; i++)
         AnalyzeConnection(data, &mIdleList[i], false);
 }
-
-
--- a/netwerk/cache2/CacheIOThread.cpp
+++ b/netwerk/cache2/CacheIOThread.cpp
@@ -236,15 +236,16 @@ NS_IMETHODIMP CacheIOThread::OnDispatche
   return NS_OK;
 }
 
 NS_IMETHODIMP CacheIOThread::OnProcessNextEvent(nsIThreadInternal *thread, bool mayWait, uint32_t recursionDepth)
 {
   return NS_OK;
 }
 
-NS_IMETHODIMP CacheIOThread::AfterProcessNextEvent(nsIThreadInternal *thread, uint32_t recursionDepth)
+NS_IMETHODIMP CacheIOThread::AfterProcessNextEvent(nsIThreadInternal *thread, uint32_t recursionDepth,
+                                                   bool eventWasProcessed)
 {
   return NS_OK;
 }
 
 } // net
 } // mozilla
--- a/widget/cocoa/nsAppShell.h
+++ b/widget/cocoa/nsAppShell.h
@@ -65,17 +65,18 @@ public:
 
   nsresult Init();
 
   NS_IMETHOD Run(void);
   NS_IMETHOD Exit(void);
   NS_IMETHOD OnProcessNextEvent(nsIThreadInternal *aThread, bool aMayWait,
                                 uint32_t aRecursionDepth);
   NS_IMETHOD AfterProcessNextEvent(nsIThreadInternal *aThread,
-                                   uint32_t aRecursionDepth);
+                                   uint32_t aRecursionDepth,
+                                   bool aEventWasProcessed);
 
   // public only to be visible to Objective-C code that must call it
   void WillTerminate();
 
 protected:
   virtual ~nsAppShell();
 
   virtual void ScheduleNativeEventCallback();
--- a/widget/cocoa/nsAppShell.mm
+++ b/widget/cocoa/nsAppShell.mm
@@ -835,33 +835,35 @@ nsAppShell::OnProcessNextEvent(nsIThread
 //
 // This nsIThreadObserver method is called after event processing is complete.
 // The Cocoa implementation cleans up the autorelease pool create by the
 // previous OnProcessNextEvent call.
 //
 // public
 NS_IMETHODIMP
 nsAppShell::AfterProcessNextEvent(nsIThreadInternal *aThread,
-                                  uint32_t aRecursionDepth)
+                                  uint32_t aRecursionDepth,
+                                  bool aEventWasProcessed)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   mRecursionDepth = aRecursionDepth;
 
   CFIndex count = ::CFArrayGetCount(mAutoreleasePools);
 
   NS_ASSERTION(mAutoreleasePools && count,
                "Processed an event, but there's no autorelease pool?");
 
   const NSAutoreleasePool* pool = static_cast<const NSAutoreleasePool*>
     (::CFArrayGetValueAtIndex(mAutoreleasePools, count - 1));
   ::CFArrayRemoveValueAtIndex(mAutoreleasePools, count - 1);
   [pool release];
 
-  return nsBaseAppShell::AfterProcessNextEvent(aThread, aRecursionDepth);
+  return nsBaseAppShell::AfterProcessNextEvent(aThread, aRecursionDepth,
+                                               aEventWasProcessed);
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 
 // AppShellDelegate implementation
 
 
--- a/widget/xpwidgets/nsBaseAppShell.cpp
+++ b/widget/xpwidgets/nsBaseAppShell.cpp
@@ -394,17 +394,18 @@ nsBaseAppShell::ScheduleSyncSection(nsIR
   if (!NS_HasPendingEvents(thread) && !DispatchDummyEvent(thread)) {
     RunSyncSections(true, 0);
   }
 }
 
 // Called from the main thread
 NS_IMETHODIMP
 nsBaseAppShell::AfterProcessNextEvent(nsIThreadInternal *thr,
-                                      uint32_t recursionDepth)
+                                      uint32_t recursionDepth,
+                                      bool eventWasProcessed)
 {
   // We've just finished running an event, so we're in a stable state. 
   RunSyncSections(true, recursionDepth);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsBaseAppShell::Observe(nsISupports *subject, const char *topic,
--- a/xpcom/threads/LazyIdleThread.cpp
+++ b/xpcom/threads/LazyIdleThread.cpp
@@ -496,24 +496,27 @@ LazyIdleThread::OnProcessNextEvent(nsITh
                                    bool /* aMayWait */,
                                    uint32_t /* aRecursionDepth */)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 LazyIdleThread::AfterProcessNextEvent(nsIThreadInternal* /* aThread */,
-                                      uint32_t /* aRecursionDepth */)
+                                      uint32_t /* aRecursionDepth */,
+                                      bool aEventWasProcessed)
 {
   bool shouldNotifyIdle;
   {
     MutexAutoLock lock(mMutex);
 
-    MOZ_ASSERT(mPendingEventCount, "Mismatched calls to observer methods!");
-    --mPendingEventCount;
+    if (aEventWasProcessed) {
+      MOZ_ASSERT(mPendingEventCount, "Mismatched calls to observer methods!");
+      --mPendingEventCount;
+    }
 
     if (mThreadIsShuttingDown) {
       // We're shutting down, no need to fire any timer.
       return NS_OK;
     }
 
     shouldNotifyIdle = !mPendingEventCount;
     if (shouldNotifyIdle) {
--- a/xpcom/threads/nsIThreadInternal.idl
+++ b/xpcom/threads/nsIThreadInternal.idl
@@ -1,18 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIThread.idl"
 
+interface nsIRunnable;
 interface nsIThreadObserver;
-interface nsIThreadEventFilter;
 
 /**
  * The XPCOM thread object implements this interface, which allows a consumer
  * to observe dispatch activity on the thread.
  */
 [scriptable, uuid(504e9e1f-70e1-4f33-a785-5840a4680414)]
 interface nsIThreadInternal : nsIThread
 {
@@ -28,21 +28,22 @@ interface nsIThreadInternal : nsIThread
   /**
    * The current recursion depth, 0 when no events are running, 1 when a single
    * event is running, and higher when nested events are running. Must only be
    * called on the target thread.
    */
   readonly attribute unsigned long recursionDepth;
 
   /**
-   * Add an observer that will *only* receive onProcessNextEvent and
-   * afterProcessNextEvent callbacks. Always called on the target thread, and
-   * the implementation does not have to be threadsafe. Order of callbacks is
-   * not guaranteed (i.e. afterProcessNextEvent may be called first depending on
-   * whether or not the observer is added in a nested loop). Holds a strong ref.
+   * Add an observer that will *only* receive onProcessNextEvent,
+   * beforeProcessNextEvent. and afterProcessNextEvent callbacks. Always called
+   * on the target thread, and the implementation does not have to be
+   * threadsafe. Order of callbacks is not guaranteed (i.e.
+   * afterProcessNextEvent may be called first depending on whether or not the
+   * observer is added in a nested loop). Holds a strong ref.
    */
   void addObserver(in nsIThreadObserver observer);
 
   /**
    * Remove an observer added via the addObserver call. Once removed the
    * observer will never be called again by the thread.
    */
   void removeObserver(in nsIThreadObserver observer);
@@ -72,49 +73,56 @@ interface nsIThreadInternal : nsIThread
  * 
  * NOTE: It is valid to change the thread's observer during a call to an
  *       observer method.
  *
  * NOTE: Will be split into two interfaces soon: one for onProcessNextEvent and
  *       afterProcessNextEvent, then another that inherits the first and adds
  *       onDispatchedEvent.
  */
-[scriptable, uuid(81D0B509-F198-4417-8020-08EB4271491F)]
+[scriptable, uuid(09b424c3-26b0-4128-9039-d66f85b02c63)]
 interface nsIThreadObserver : nsISupports
 {
   /**
    * This method is called after an event has been dispatched to the thread.
    * This method may be called from any thread. 
    *
    * @param thread
    *   The thread where the event is being dispatched.
    */
   void onDispatchedEvent(in nsIThreadInternal thread);
 
   /**
-   * This method is called (from nsIThread::ProcessNextEvent) before an event
-   * is processed.  This method is only called on the target thread.
+   * This method is called when nsIThread::ProcessNextEvent is called.  It does
+   * not guarantee that an event is actually going to be processed.  This method
+   * is only called on the target thread.
    *
    * @param thread
    *   The thread being asked to process another event.
    * @param mayWait
    *   Indicates whether or not the method is allowed to block the calling
    *   thread.  For example, this parameter is false during thread shutdown.
    * @param recursionDepth
    *   Indicates the number of calls to ProcessNextEvent on the call stack in
    *   addition to the current call.
    */
   void onProcessNextEvent(in nsIThreadInternal thread, in boolean mayWait,
                           in unsigned long recursionDepth);
 
   /**
    * This method is called (from nsIThread::ProcessNextEvent) after an event
-   * is processed.  This method is only called on the target thread.
+   * is processed.  It does not guarantee that an event was actually processed
+   * (depends on the value of |eventWasProcessed|.  This method is only called
+   * on the target thread.
    *
    * @param thread
    *   The thread that processed another event.
    * @param recursionDepth
    *   Indicates the number of calls to ProcessNextEvent on the call stack in
    *   addition to the current call.
+   * @param eventWasProcessed
+   *   Indicates whether an event was actually processed. May be false if the
+   *   |mayWait| flag was false when calling nsIThread::ProcessNextEvent().
    */
   void afterProcessNextEvent(in nsIThreadInternal thread,
-                             in unsigned long recursionDepth);
+                             in unsigned long recursionDepth,
+                             in bool eventWasProcessed);
 };
--- a/xpcom/threads/nsThread.cpp
+++ b/xpcom/threads/nsThread.cpp
@@ -614,23 +614,24 @@ nsThread::ProcessNextEvent(bool mayWait,
       MOZ_ASSERT(ShuttingDown(),
                  "This should only happen when shutting down");
       rv = NS_ERROR_UNEXPECTED;
     }
   }
 
   --mRunningEvent;
 
-  NOTIFY_EVENT_OBSERVERS(AfterProcessNextEvent, (this, mRunningEvent));
+  NOTIFY_EVENT_OBSERVERS(AfterProcessNextEvent,
+                         (this, mRunningEvent, *result));
 
   if (obs)
-    obs->AfterProcessNextEvent(this, mRunningEvent);
+    obs->AfterProcessNextEvent(this, mRunningEvent, *result);
 
   if (notifyMainThreadObserver && sMainThreadObserver)
-    sMainThreadObserver->AfterProcessNextEvent(this, mRunningEvent);
+    sMainThreadObserver->AfterProcessNextEvent(this, mRunningEvent, *result);
 
   return rv;
 }
 
 //-----------------------------------------------------------------------------
 // nsISupportsPriority
 
 NS_IMETHODIMP