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/PerformanceCounter.h" 14 #include "mozilla/RefPtr.h" 15 #include "mozilla/dom/SafeRefPtr.h" 16 #include "nsISupports.h" 17 #include "nsThread.h" 18 #include "nscore.h" 19 20 class nsIRunnable; 21 22 namespace mozilla { 23 class Runnable; 24 25 namespace dom { 26 27 class WorkerRunnable; 28 class WorkerPrivate; 29 template <class> 30 class WorkerPrivateParent; 31 32 namespace workerinternals { 33 class RuntimeService; 34 } 35 36 // This class lets us restrict the public methods that can be called on 37 // WorkerThread to RuntimeService and WorkerPrivate without letting them gain 38 // full access to private methods (as would happen if they were simply friends). 39 class WorkerThreadFriendKey { 40 friend class workerinternals::RuntimeService; 41 friend class WorkerPrivate; 42 friend class WorkerPrivateParent<WorkerPrivate>; 43 44 WorkerThreadFriendKey(); 45 ~WorkerThreadFriendKey(); 46 }; 47 48 class WorkerThread final : public nsThread { 49 class Observer; 50 51 Mutex mLock; 52 CondVar mWorkerPrivateCondVar; 53 54 // Protected by nsThread::mLock. 55 WorkerPrivate* mWorkerPrivate; 56 57 // Only touched on the target thread. 58 RefPtr<Observer> mObserver; 59 60 // Protected by nsThread::mLock and waited on with mWorkerPrivateCondVar. 61 uint32_t mOtherThreadsDispatchingViaEventTarget; 62 63 #ifdef DEBUG 64 // Protected by nsThread::mLock. 65 bool mAcceptingNonWorkerRunnables; 66 #endif 67 68 // Using this struct we restrict access to the constructor while still being 69 // able to use MakeSafeRefPtr. 70 struct ConstructorKey {}; 71 72 public: 73 explicit WorkerThread(ConstructorKey); 74 75 static SafeRefPtr<WorkerThread> Create(const WorkerThreadFriendKey& aKey); 76 77 void SetWorker(const WorkerThreadFriendKey& aKey, 78 WorkerPrivate* aWorkerPrivate); 79 80 nsresult DispatchPrimaryRunnable(const WorkerThreadFriendKey& aKey, 81 already_AddRefed<nsIRunnable> aRunnable); 82 83 nsresult DispatchAnyThread(const WorkerThreadFriendKey& aKey, 84 already_AddRefed<WorkerRunnable> aWorkerRunnable); 85 86 uint32_t RecursionDepth(const WorkerThreadFriendKey& aKey) const; 87 88 PerformanceCounter* GetPerformanceCounter(nsIRunnable* aEvent) const override; 89 90 NS_INLINE_DECL_REFCOUNTING_INHERITED(WorkerThread, nsThread) 91 92 private: 93 ~WorkerThread(); 94 95 // This should only be called by consumers that have an 96 // nsIEventTarget/nsIThread pointer. 97 NS_IMETHOD 98 Dispatch(already_AddRefed<nsIRunnable> aRunnable, uint32_t aFlags) override; 99 100 NS_IMETHOD 101 DispatchFromScript(nsIRunnable* aRunnable, uint32_t aFlags) override; 102 103 NS_IMETHOD 104 DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t) override; 105 106 void IncrementDispatchCounter(); 107 }; 108 109 } // namespace dom 110 } // namespace mozilla 111 112 #endif // mozilla_dom_workers_WorkerThread_h__ 113