WorkerThread.h (3670B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 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/. */ 6 7 #ifndef mozilla_dom_workers_WorkerThread_h__ 8 #define mozilla_dom_workers_WorkerThread_h__ 9 10 #include "mozilla/AlreadyAddRefed.h" 11 #include "mozilla/CondVar.h" 12 #include "mozilla/Mutex.h" 13 #include "mozilla/RefPtr.h" 14 #include "mozilla/dom/SafeRefPtr.h" 15 #include "nsISupports.h" 16 #include "nsThread.h" 17 #include "nscore.h" 18 19 class nsIRunnable; 20 21 namespace mozilla { 22 class Runnable; 23 24 namespace dom { 25 26 class WorkerRunnable; 27 class WorkerPrivate; 28 namespace workerinternals { 29 class RuntimeService; 30 } 31 32 // This class lets us restrict the public methods that can be called on 33 // WorkerThread to RuntimeService and WorkerPrivate without letting them gain 34 // full access to private methods (as would happen if they were simply friends). 35 class WorkerThreadFriendKey { 36 friend class workerinternals::RuntimeService; 37 friend class WorkerPrivate; 38 39 WorkerThreadFriendKey(); 40 ~WorkerThreadFriendKey(); 41 }; 42 43 class WorkerThread final : public nsThread { 44 class Observer; 45 46 Mutex mLock MOZ_UNANNOTATED; 47 CondVar mWorkerPrivateCondVar; 48 49 // Protected by nsThread::mLock. 50 WorkerPrivate* mWorkerPrivate; 51 52 // Only touched on the target thread. 53 RefPtr<Observer> mObserver; 54 55 // Protected by nsThread::mLock and waited on with mWorkerPrivateCondVar. 56 uint32_t mOtherThreadsDispatchingViaEventTarget; 57 58 #ifdef DEBUG 59 // Protected by nsThread::mLock. 60 bool mAcceptingNonWorkerRunnables; 61 #endif 62 63 // Using this struct we restrict access to the constructor while still being 64 // able to use MakeSafeRefPtr. 65 struct ConstructorKey {}; 66 67 public: 68 explicit WorkerThread(ConstructorKey); 69 70 static SafeRefPtr<WorkerThread> Create(const WorkerThreadFriendKey& aKey); 71 72 void SetWorker(const WorkerThreadFriendKey& aKey, 73 WorkerPrivate* aWorkerPrivate); 74 75 // This method is used to decouple the connection with the WorkerPrivate which 76 // is set in SetWorker(). And it also clears all pending runnables on this 77 // WorkerThread. 78 // After decoupling, WorkerThreadRunnable can not run on this WorkerThread 79 // anymore, since WorkerPrivate is invalid. 80 void ClearEventQueueAndWorker(const WorkerThreadFriendKey& aKey); 81 82 nsresult DispatchPrimaryRunnable(const WorkerThreadFriendKey& aKey, 83 already_AddRefed<nsIRunnable> aRunnable); 84 85 nsresult DispatchAnyThread(const WorkerThreadFriendKey& aKey, 86 RefPtr<WorkerRunnable> aWorkerRunnable); 87 88 uint32_t RecursionDepth(const WorkerThreadFriendKey& aKey) const; 89 90 // Override HasPendingEvents to allow HasPendingEvents could be accessed by 91 // the parent thread. WorkerPrivate::IsEligibleForCC calls this method on the 92 // parent thread to check if there is any pending events on the worker thread. 93 NS_IMETHOD HasPendingEvents(bool* aHasPendingEvents) override; 94 95 NS_INLINE_DECL_REFCOUNTING_INHERITED(WorkerThread, nsThread) 96 97 private: 98 ~WorkerThread(); 99 100 // This should only be called by consumers that have an 101 // nsIEventTarget/nsIThread pointer. 102 NS_IMETHOD 103 Dispatch(already_AddRefed<nsIRunnable> aRunnable, 104 DispatchFlags aFlags) override; 105 106 NS_IMETHOD 107 DispatchFromScript(nsIRunnable* aRunnable, DispatchFlags aFlags) override; 108 109 NS_IMETHOD 110 DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t) override; 111 }; 112 113 } // namespace dom 114 } // namespace mozilla 115 116 #endif // mozilla_dom_workers_WorkerThread_h__