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 #include "WorkerEventTarget.h"
14 class WrappedControlRunnable final
: public WorkerControlRunnable
{
15 nsCOMPtr
<nsIRunnable
> mInner
;
17 ~WrappedControlRunnable() {}
20 WrappedControlRunnable(WorkerPrivate
* aWorkerPrivate
,
21 already_AddRefed
<nsIRunnable
>&& aInner
)
22 : WorkerControlRunnable(aWorkerPrivate
, WorkerThreadUnchangedBusyCount
),
25 virtual bool PreDispatch(WorkerPrivate
* aWorkerPrivate
) override
{
26 // Silence bad assertions, this can be dispatched from any thread.
30 virtual void PostDispatch(WorkerPrivate
* aWorkerPrivate
,
31 bool aDispatchResult
) override
{
32 // Silence bad assertions, this can be dispatched from any thread.
35 bool WorkerRun(JSContext
* aCx
, WorkerPrivate
* aWorkerPrivate
) override
{
40 nsresult
Cancel() override
{
41 nsCOMPtr
<nsICancelableRunnable
> cr
= do_QueryInterface(mInner
);
43 // If the inner runnable is not cancellable, then just do the normal
44 // WorkerControlRunnable thing. This will end up calling Run().
46 WorkerControlRunnable::Cancel();
50 // Otherwise call the inner runnable's Cancel() and treat this like
51 // a WorkerRunnable cancel. We can't call WorkerControlRunnable::Cancel()
52 // in this case since that would result in both Run() and the inner
53 // Cancel() being called.
54 Unused
<< cr
->Cancel();
55 return WorkerRunnable::Cancel();
59 } // anonymous namespace
61 NS_IMPL_ISUPPORTS(WorkerEventTarget
, nsIEventTarget
, nsISerialEventTarget
)
63 WorkerEventTarget::WorkerEventTarget(WorkerPrivate
* aWorkerPrivate
,
65 : mMutex("WorkerEventTarget"),
66 mWorkerPrivate(aWorkerPrivate
),
67 mBehavior(aBehavior
) {
68 MOZ_DIAGNOSTIC_ASSERT(mWorkerPrivate
);
71 void WorkerEventTarget::ForgetWorkerPrivate(WorkerPrivate
* aWorkerPrivate
) {
72 MutexAutoLock
lock(mMutex
);
73 MOZ_DIAGNOSTIC_ASSERT(!mWorkerPrivate
|| mWorkerPrivate
== aWorkerPrivate
);
74 mWorkerPrivate
= nullptr;
78 WorkerEventTarget::DispatchFromScript(nsIRunnable
* aRunnable
, uint32_t aFlags
) {
79 nsCOMPtr
<nsIRunnable
> runnable(aRunnable
);
80 return Dispatch(runnable
.forget(), aFlags
);
84 WorkerEventTarget::Dispatch(already_AddRefed
<nsIRunnable
> aRunnable
,
86 nsCOMPtr
<nsIRunnable
> runnable(aRunnable
);
88 MutexAutoLock
lock(mMutex
);
90 if (!mWorkerPrivate
) {
91 return NS_ERROR_FAILURE
;
94 if (mBehavior
== Behavior::Hybrid
) {
95 RefPtr
<WorkerRunnable
> r
=
96 mWorkerPrivate
->MaybeWrapAsWorkerRunnable(runnable
.forget());
101 runnable
= r
.forget();
104 RefPtr
<WorkerControlRunnable
> r
=
105 new WrappedControlRunnable(mWorkerPrivate
, runnable
.forget());
106 if (!r
->Dispatch()) {
107 return NS_ERROR_FAILURE
;
114 WorkerEventTarget::DelayedDispatch(already_AddRefed
<nsIRunnable
>, uint32_t) {
115 return NS_ERROR_NOT_IMPLEMENTED
;
119 WorkerEventTarget::IsOnCurrentThreadInfallible() {
120 MutexAutoLock
lock(mMutex
);
122 if (!mWorkerPrivate
) {
126 return mWorkerPrivate
->IsOnCurrentThread();
130 WorkerEventTarget::IsOnCurrentThread(bool* aIsOnCurrentThread
) {
131 MOZ_ASSERT(aIsOnCurrentThread
);
132 *aIsOnCurrentThread
= IsOnCurrentThreadInfallible();
137 } // namespace mozilla