Bug 719154, remove the implementation of chained and filtered event queues now that they are no longer needed, r=jlebar
authorBenjamin Smedberg <benjamin@smedbergs.us>
Fri, 23 Mar 2012 14:45:41 -0400
changeset 93503 1b05e9751f3477275a7bb566fc20f3941411af1d
parent 93502 8b15746f43a1184d0747d270354b29233fc5fdcf
child 93504 73db7a5e57f7c07ba490f87f5232b0e95d19c07e
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjlebar
bugs719154
milestone14.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 719154, remove the implementation of chained and filtered event queues now that they are no longer needed, r=jlebar
xpcom/threads/nsIThreadInternal.idl
xpcom/threads/nsThread.cpp
xpcom/threads/nsThread.h
--- a/xpcom/threads/nsIThreadInternal.idl
+++ b/xpcom/threads/nsIThreadInternal.idl
@@ -40,49 +40,29 @@
 
 interface nsIThreadObserver;
 interface nsIThreadEventFilter;
 
 /**
  * The XPCOM thread object implements this interface, which allows a consumer
  * to observe dispatch activity on the thread.
  */
-[scriptable, uuid(e0d35c22-53d5-4b48-8627-93e05b94cf2c)]
+[scriptable, uuid(504e9e1f-70e1-4f33-a785-5840a4680414)]
 interface nsIThreadInternal : nsIThread
 {
   /**
    * Get/set the current thread observer (may be null).  This attribute may be
    * read from any thread, but must only be set on the thread corresponding to
    * this thread object.  The observer will be released on the thread
    * corresponding to this thread object after all other events have been
    * processed during a call to Shutdown.
    */
   attribute nsIThreadObserver observer;
 
   /**
-   * This method causes any events currently enqueued on the thread to be
-   * suppressed until PopEventQueue is called.  Additionally, any new events
-   * dispatched to the thread will only be processed if they are accepted by
-   * the given filter.  If the filter is null, then new events are accepted.
-   * Calls to PushEventQueue may be nested and must each be paired with a call
-   * to PopEventQueue in order to restore the original state of the thread.
-   *
-   * @param filter
-   *   The thread event filter to apply to dispatched events, or null to accept
-   *   all dispatched events.
-   */
-  void pushEventQueue(in nsIThreadEventFilter filter);
-
-  /**
-   * Revert a call to PushEventQueue.  When an event queue is popped, any
-   * events remaining in the queue are appended to the elder queue.
-   */
-  void popEventQueue();
-
-  /**
    * 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
@@ -165,26 +145,8 @@ interface nsIThreadObserver : nsISupport
    *   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.
    */
   void afterProcessNextEvent(in nsIThreadInternal thread,
                              in unsigned long recursionDepth);
 };
-
-/**
- * Interface passed to the nsIThreadInternal::PushEventQueue method.
- */
-[scriptable, uuid(a0605c0b-17f5-4681-b8cd-a1cd75d42559)]
-interface nsIThreadEventFilter : nsISupports
-{
-  /**
-   * This method is called to determine whether or not an event may be accepted
-   * by a "nested" event queue (see nsIThreadInternal::PushEventQueue).
-   *
-   * @param event
-   *   The event being dispatched.
-   *
-   * WARNING: This method must not make any calls on the thread object.
-   */
-  [notxpcom] boolean acceptEvent(in nsIRunnable event);
-};
--- a/xpcom/threads/nsThread.cpp
+++ b/xpcom/threads/nsThread.cpp
@@ -291,17 +291,17 @@ nsThread::ThreadFunc(void *arg)
   // Do NS_ProcessPendingEvents but with special handling to set
   // mEventsAreDoomed atomically with the removal of the last event. The key
   // invariant here is that we will never permit PutEvent to succeed if the
   // event would be left in the queue after our final call to
   // NS_ProcessPendingEvents.
   while (true) {
     {
       MutexAutoLock lock(self->mLock);
-      if (!self->mEvents->HasPendingEvent()) {
+      if (!self->mEvents.HasPendingEvent()) {
         // No events in the queue, so we will stop now. Don't let any more
         // events be added, since they won't be processed. It is critical
         // that no PutEvent can occur between testing that the event queue is
         // empty and setting mEventsAreDoomed!
         self->mEventsAreDoomed = true;
         break;
       }
     }
@@ -320,17 +320,16 @@ nsThread::ThreadFunc(void *arg)
 
   NS_RELEASE(self);
 }
 
 //-----------------------------------------------------------------------------
 
 nsThread::nsThread(MainThreadFlag aMainThread, PRUint32 aStackSize)
   : mLock("nsThread.mLock")
-  , mEvents(&mEventsRoot)
   , mPriority(PRIORITY_NORMAL)
   , mThread(nsnull)
   , mRunningEvent(0)
   , mStackSize(aStackSize)
   , mShutdownContext(nsnull)
   , mShutdownRequired(false)
   , mEventsAreDoomed(false)
   , mIsMainThread(aMainThread)
@@ -361,17 +360,17 @@ nsThread::Init()
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   // ThreadFunc will wait for this event to be run before it tries to access
   // mThread.  By delaying insertion of this event into the queue, we ensure
   // that mThread is set properly.
   {
     MutexAutoLock lock(mLock);
-    mEvents->PutEvent(startup);
+    mEvents.PutEvent(startup);
   }
 
   // Wait for thread to call ThreadManager::SetupCurrentThread, which completes
   // initialization of ThreadFunc.
   startup->Wait();
   return NS_OK;
 }
 
@@ -388,17 +387,17 @@ nsresult
 nsThread::PutEvent(nsIRunnable *event)
 {
   {
     MutexAutoLock lock(mLock);
     if (mEventsAreDoomed) {
       NS_WARNING("An event was posted to a thread that will never run it (rejected)");
       return NS_ERROR_UNEXPECTED;
     }
-    if (!mEvents->PutEvent(event))
+    if (!mEvents.PutEvent(event))
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   nsCOMPtr<nsIThreadObserver> obs = GetObserver();
   if (obs)
     obs->OnDispatchedEvent(this);
 
   return NS_OK;
@@ -518,17 +517,17 @@ nsThread::Shutdown()
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsThread::HasPendingEvents(bool *result)
 {
   NS_ENSURE_STATE(PR_GetCurrentThread() == mThread);
 
-  *result = mEvents->GetEvent(false, nsnull);
+  *result = mEvents.GetEvent(false, nsnull);
   return NS_OK;
 }
 
 #ifdef MOZ_CANARY
 void canary_alarm_handler (int signum);
 
 class Canary {
 //XXX ToDo: support nested loops
@@ -630,17 +629,17 @@ nsThread::ProcessNextEvent(bool mayWait,
 
   {
     // Scope for |event| to make sure that its destructor fires while
     // mRunningEvent has been incremented, since that destructor can
     // also do work.
 
     // If we are shutting down, then do not wait for new events.
     nsCOMPtr<nsIRunnable> event;
-    mEvents->GetEvent(mayWait && !ShuttingDown(), getter_AddRefs(event));
+    mEvents.GetEvent(mayWait && !ShuttingDown(), getter_AddRefs(event));
 
 #ifdef NS_FUNCTION_TIMER
     char message[1024] = {'\0'};
     if (MAIN_THREAD == mIsMainThread) {
         mozilla::FunctionTimer::ft_snprintf(message, sizeof(message), 
                                             "@ Main Thread Event %p", (void*)event.get());
     }
     // If message is empty, it means that we're not on the main thread, and
@@ -734,59 +733,16 @@ nsThread::SetObserver(nsIThreadObserver 
   NS_ENSURE_STATE(PR_GetCurrentThread() == mThread);
 
   MutexAutoLock lock(mLock);
   mObserver = obs;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsThread::PushEventQueue(nsIThreadEventFilter *filter)
-{
-  nsChainedEventQueue *queue = new nsChainedEventQueue(filter);
-
-  MutexAutoLock lock(mLock);
-  queue->mNext = mEvents;
-  mEvents = queue;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsThread::PopEventQueue()
-{
-  MutexAutoLock lock(mLock);
-
-  // Make sure we do not pop too many!
-  NS_ENSURE_STATE(mEvents != &mEventsRoot);
-
-  nsChainedEventQueue *queue = mEvents;
-  mEvents = mEvents->mNext;
-
-  nsCOMPtr<nsIRunnable> event;
-  while (queue->GetEvent(false, getter_AddRefs(event)))
-    mEvents->PutEvent(event);
-
-  delete queue;
-  
-  return NS_OK;
-}
-
-bool
-nsThread::nsChainedEventQueue::PutEvent(nsIRunnable *event)
-{
-  bool val;
-  if (!mFilter || mFilter->AcceptEvent(event)) {
-    val = mQueue.PutEvent(event);
-  } else {
-    val = mNext->PutEvent(event);
-  }
-  return val;
-}
-
-NS_IMETHODIMP
 nsThread::GetRecursionDepth(PRUint32 *depth)
 {
   NS_ENSURE_ARG_POINTER(depth);
   NS_ENSURE_STATE(PR_GetCurrentThread() == mThread);
 
   *depth = mRunningEvent;
   return NS_OK;
 }
--- a/xpcom/threads/nsThread.h
+++ b/xpcom/threads/nsThread.h
@@ -93,57 +93,33 @@ private:
   already_AddRefed<nsIThreadObserver> GetObserver() {
     nsIThreadObserver *obs;
     nsThread::GetObserver(&obs);
     return already_AddRefed<nsIThreadObserver>(obs);
   }
 
   // Wrappers for event queue methods:
   bool GetEvent(bool mayWait, nsIRunnable **event) {
-    return mEvents->GetEvent(mayWait, event);
+    return mEvents.GetEvent(mayWait, event);
   }
   nsresult PutEvent(nsIRunnable *event);
 
-  // Wrapper for nsEventQueue that supports chaining.
-  class nsChainedEventQueue {
-  public:
-    nsChainedEventQueue(nsIThreadEventFilter *filter = nsnull)
-      : mNext(nsnull), mFilter(filter) {
-    }
-
-    bool GetEvent(bool mayWait, nsIRunnable **event) {
-      return mQueue.GetEvent(mayWait, event);
-    }
-
-    bool PutEvent(nsIRunnable *event);
-    
-    bool HasPendingEvent() {
-      return mQueue.HasPendingEvent();
-    }
-
-    class nsChainedEventQueue *mNext;
-  private:
-    nsCOMPtr<nsIThreadEventFilter> mFilter;
-    nsEventQueue mQueue;
-  };
-
   // This lock protects access to mObserver, mEvents and mEventsAreDoomed.
   // All of those fields are only modified on the thread itself (never from
   // another thread).  This means that we can avoid holding the lock while
   // using mObserver and mEvents on the thread itself.  When calling PutEvent
   // on mEvents, we have to hold the lock to synchronize with PopEventQueue.
   mozilla::Mutex mLock;
 
   nsCOMPtr<nsIThreadObserver> mObserver;
 
   // Only accessed on the target thread.
   nsAutoTObserverArray<nsCOMPtr<nsIThreadObserver>, 2> mEventObservers;
 
-  nsChainedEventQueue *mEvents;   // never null
-  nsChainedEventQueue  mEventsRoot;
+  nsEventQueue  mEvents;
 
   PRInt32   mPriority;
   PRThread *mThread;
   PRUint32  mRunningEvent;  // counter
   PRUint32  mStackSize;
 
   struct nsThreadShutdownContext *mShutdownContext;