xpcom/threads/nsThread.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef nsThread_h__
     8 #define nsThread_h__
    10 #include "mozilla/Mutex.h"
    11 #include "nsIThreadInternal.h"
    12 #include "nsISupportsPriority.h"
    13 #include "nsEventQueue.h"
    14 #include "nsThreadUtils.h"
    15 #include "nsString.h"
    16 #include "nsTObserverArray.h"
    17 #include "mozilla/Attributes.h"
    18 #include "nsAutoPtr.h"
    20 // A native thread
    21 class nsThread : public nsIThreadInternal,
    22                  public nsISupportsPriority
    23 {
    24 public:
    25   NS_DECL_THREADSAFE_ISUPPORTS
    26   NS_DECL_NSIEVENTTARGET
    27   NS_DECL_NSITHREAD
    28   NS_DECL_NSITHREADINTERNAL
    29   NS_DECL_NSISUPPORTSPRIORITY
    31   enum MainThreadFlag {
    32     MAIN_THREAD,
    33     NOT_MAIN_THREAD
    34   };
    36   nsThread(MainThreadFlag aMainThread, uint32_t aStackSize);
    38   // Initialize this as a wrapper for a new PRThread.
    39   nsresult Init();
    41   // Initialize this as a wrapper for the current PRThread.
    42   nsresult InitCurrentThread();
    44   // The PRThread corresponding to this thread.
    45   PRThread *GetPRThread() { return mThread; }
    47   // If this flag is true, then the nsThread was created using
    48   // nsIThreadManager::NewThread.
    49   bool ShutdownRequired() { return mShutdownRequired; }
    51   // Clear the observer list.
    52   void ClearObservers() { mEventObservers.Clear(); }
    54   static nsresult
    55   SetMainThreadObserver(nsIThreadObserver* aObserver);
    57 protected:
    58   static nsIThreadObserver* sMainThreadObserver;
    60   class nsChainedEventQueue;
    62   class nsNestedEventTarget;
    63   friend class nsNestedEventTarget;
    65   friend class nsThreadShutdownEvent;
    67   virtual ~nsThread();
    69   bool ShuttingDown() { return mShutdownContext != nullptr; }
    71   static void ThreadFunc(void *arg);
    73   // Helper
    74   already_AddRefed<nsIThreadObserver> GetObserver() {
    75     nsIThreadObserver *obs;
    76     nsThread::GetObserver(&obs);
    77     return already_AddRefed<nsIThreadObserver>(obs);
    78   }
    80   // Wrappers for event queue methods:
    81   bool GetEvent(bool mayWait, nsIRunnable **event) {
    82     return mEvents->GetEvent(mayWait, event);
    83   }
    84   nsresult PutEvent(nsIRunnable *event, nsNestedEventTarget *target);
    86   nsresult DispatchInternal(nsIRunnable *event, uint32_t flags,
    87                             nsNestedEventTarget *target);
    89   // Wrapper for nsEventQueue that supports chaining.
    90   class nsChainedEventQueue {
    91   public:
    92     nsChainedEventQueue()
    93       : mNext(nullptr) {
    94     }
    96     bool GetEvent(bool mayWait, nsIRunnable **event) {
    97       return mQueue.GetEvent(mayWait, event);
    98     }
   100     bool PutEvent(nsIRunnable *event) {
   101       return mQueue.PutEvent(event);
   102     }
   104     bool HasPendingEvent() {
   105       return mQueue.HasPendingEvent();
   106     }
   108     nsChainedEventQueue *mNext;
   109     nsRefPtr<nsNestedEventTarget> mEventTarget;
   111   private:
   112     nsEventQueue mQueue;
   113   };
   115   class nsNestedEventTarget MOZ_FINAL : public nsIEventTarget {
   116   public:
   117     NS_DECL_THREADSAFE_ISUPPORTS
   118     NS_DECL_NSIEVENTTARGET
   120     nsNestedEventTarget(nsThread *thread, nsChainedEventQueue *queue)
   121       : mThread(thread), mQueue(queue) {
   122     }
   124     nsRefPtr<nsThread> mThread;
   126     // This is protected by mThread->mLock.
   127     nsChainedEventQueue* mQueue;
   129   private:
   130     ~nsNestedEventTarget() {}
   131   };
   133   // This lock protects access to mObserver, mEvents and mEventsAreDoomed.
   134   // All of those fields are only modified on the thread itself (never from
   135   // another thread).  This means that we can avoid holding the lock while
   136   // using mObserver and mEvents on the thread itself.  When calling PutEvent
   137   // on mEvents, we have to hold the lock to synchronize with PopEventQueue.
   138   mozilla::Mutex mLock;
   140   nsCOMPtr<nsIThreadObserver> mObserver;
   142   // Only accessed on the target thread.
   143   nsAutoTObserverArray<nsCOMPtr<nsIThreadObserver>, 2> mEventObservers;
   145   nsChainedEventQueue *mEvents;   // never null
   146   nsChainedEventQueue  mEventsRoot;
   148   int32_t   mPriority;
   149   PRThread *mThread;
   150   uint32_t  mRunningEvent;  // counter
   151   uint32_t  mStackSize;
   153   struct nsThreadShutdownContext *mShutdownContext;
   155   bool mShutdownRequired;
   156   // Set to true when events posted to this thread will never run.
   157   bool mEventsAreDoomed;
   158   MainThreadFlag mIsMainThread;
   159 };
   161 //-----------------------------------------------------------------------------
   163 class nsThreadSyncDispatch : public nsRunnable {
   164 public:
   165   nsThreadSyncDispatch(nsIThread *origin, nsIRunnable *task)
   166     : mOrigin(origin), mSyncTask(task), mResult(NS_ERROR_NOT_INITIALIZED) {
   167   }
   169   bool IsPending() {
   170     return mSyncTask != nullptr;
   171   }
   173   nsresult Result() {
   174     return mResult;
   175   }
   177 private:
   178   NS_DECL_NSIRUNNABLE
   180   nsCOMPtr<nsIThread> mOrigin;
   181   nsCOMPtr<nsIRunnable> mSyncTask;
   182   nsresult mResult;
   183 };
   185 #if defined(XP_UNIX) && !defined(ANDROID) && !defined(DEBUG) && HAVE_UALARM \
   186   && defined(_GNU_SOURCE)
   187 # define MOZ_CANARY
   189 extern int sCanaryOutputFD;
   190 #endif
   192 #endif  // nsThread_h__

mercurial