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/. */
7 #ifndef mozilla_ThreadEventQueue_h
8 #define mozilla_ThreadEventQueue_h
10 #include "mozilla/EventQueue.h"
11 #include "mozilla/CondVar.h"
12 #include "mozilla/SynchronizedEventQueue.h"
17 class nsISerialEventTarget
;
18 class nsIThreadObserver
;
23 class ThreadEventTarget
;
25 // A ThreadEventQueue implements normal monitor-style synchronization over the
26 // EventQueue. It also implements PushEventQueue and PopEventQueue for workers
27 // (see the documentation below for an explanation of those). All threads use a
28 // ThreadEventQueue as their event queue. Although for the main thread this
29 // simply forwards events to the TaskController.
30 class ThreadEventQueue final
: public SynchronizedEventQueue
{
32 explicit ThreadEventQueue(UniquePtr
<EventQueue
> aQueue
,
33 bool aIsMainThread
= false);
35 bool PutEvent(already_AddRefed
<nsIRunnable
>&& aEvent
,
36 EventQueuePriority aPriority
) final
;
38 already_AddRefed
<nsIRunnable
> GetEvent(
39 bool aMayWait
, mozilla::TimeDuration
* aLastEventDelay
= nullptr) final
;
40 bool HasPendingEvent() final
;
42 bool ShutdownIfNoPendingEvents() final
;
44 void Disconnect(const MutexAutoLock
& aProofOfLock
) final
{}
46 nsresult
RegisterShutdownTask(nsITargetShutdownTask
* aTask
) final
;
47 nsresult
UnregisterShutdownTask(nsITargetShutdownTask
* aTask
) final
;
48 void RunShutdownTasks() final
;
50 already_AddRefed
<nsISerialEventTarget
> PushEventQueue() final
;
51 void PopEventQueue(nsIEventTarget
* aTarget
) final
;
53 already_AddRefed
<nsIThreadObserver
> GetObserver() final
;
54 already_AddRefed
<nsIThreadObserver
> GetObserverOnThread() final
;
55 void SetObserver(nsIThreadObserver
* aObserver
) final
;
57 Mutex
& MutexRef() { return mLock
; }
59 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf
) override
;
64 virtual ~ThreadEventQueue();
66 bool PutEventInternal(already_AddRefed
<nsIRunnable
>&& aEvent
,
67 EventQueuePriority aPriority
, NestedSink
* aQueue
);
69 const UniquePtr
<EventQueue
> mBaseQueue
MOZ_GUARDED_BY(mLock
);
71 struct NestedQueueItem
{
72 UniquePtr
<EventQueue
> mQueue
;
73 RefPtr
<ThreadEventTarget
> mEventTarget
;
75 NestedQueueItem(UniquePtr
<EventQueue
> aQueue
,
76 ThreadEventTarget
* aEventTarget
);
79 nsTArray
<NestedQueueItem
> mNestedQueues
MOZ_GUARDED_BY(mLock
);
82 CondVar mEventsAvailable
MOZ_GUARDED_BY(mLock
);
84 bool mEventsAreDoomed
MOZ_GUARDED_BY(mLock
) = false;
85 nsCOMPtr
<nsIThreadObserver
> mObserver
MOZ_GUARDED_BY(mLock
);
86 nsTArray
<nsCOMPtr
<nsITargetShutdownTask
>> mShutdownTasks
87 MOZ_GUARDED_BY(mLock
);
88 bool mShutdownTasksRun
MOZ_GUARDED_BY(mLock
) = false;
90 const bool mIsMainThread
;
93 } // namespace mozilla
95 #endif // mozilla_ThreadEventQueue_h