Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/workers/WorkerEventTarget.cpp
Line
Count
Source (jump to first uncovered line)
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
#include "WorkerEventTarget.h"
8
9
namespace mozilla {
10
namespace dom {
11
12
namespace {
13
14
class WrappedControlRunnable final : public WorkerControlRunnable
15
{
16
  nsCOMPtr<nsIRunnable> mInner;
17
18
  ~WrappedControlRunnable()
19
0
  {
20
0
  }
21
22
public:
23
  WrappedControlRunnable(WorkerPrivate* aWorkerPrivate,
24
                         already_AddRefed<nsIRunnable>&& aInner)
25
    : WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
26
    , mInner(aInner)
27
0
  {
28
0
  }
29
30
  virtual bool
31
  PreDispatch(WorkerPrivate* aWorkerPrivate) override
32
0
  {
33
0
    // Silence bad assertions, this can be dispatched from any thread.
34
0
    return true;
35
0
  }
36
37
  virtual void
38
  PostDispatch(WorkerPrivate* aWorkerPrivate, bool aDispatchResult) override
39
0
  {
40
0
    // Silence bad assertions, this can be dispatched from any thread.
41
0
  }
42
43
  bool
44
  WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
45
0
  {
46
0
    mInner->Run();
47
0
    return true;
48
0
  }
49
50
  nsresult
51
  Cancel() override
52
0
  {
53
0
    nsCOMPtr<nsICancelableRunnable> cr = do_QueryInterface(mInner);
54
0
55
0
    // If the inner runnable is not cancellable, then just do the normal
56
0
    // WorkerControlRunnable thing.  This will end up calling Run().
57
0
    if (!cr) {
58
0
      WorkerControlRunnable::Cancel();
59
0
      return NS_OK;
60
0
    }
61
0
62
0
    // Otherwise call the inner runnable's Cancel() and treat this like
63
0
    // a WorkerRunnable cancel.  We can't call WorkerControlRunnable::Cancel()
64
0
    // in this case since that would result in both Run() and the inner
65
0
    // Cancel() being called.
66
0
    Unused << cr->Cancel();
67
0
    return WorkerRunnable::Cancel();
68
0
  }
69
};
70
71
} // anonymous namespace
72
73
NS_IMPL_ISUPPORTS(WorkerEventTarget, nsIEventTarget, nsISerialEventTarget)
74
75
WorkerEventTarget::WorkerEventTarget(WorkerPrivate* aWorkerPrivate,
76
                                    Behavior aBehavior)
77
  : mMutex("WorkerEventTarget")
78
  , mWorkerPrivate(aWorkerPrivate)
79
  , mBehavior(aBehavior)
80
0
{
81
0
  MOZ_DIAGNOSTIC_ASSERT(mWorkerPrivate);
82
0
}
83
84
void
85
WorkerEventTarget::ForgetWorkerPrivate(WorkerPrivate* aWorkerPrivate)
86
0
{
87
0
  MutexAutoLock lock(mMutex);
88
0
  MOZ_DIAGNOSTIC_ASSERT(!mWorkerPrivate || mWorkerPrivate == aWorkerPrivate);
89
0
  mWorkerPrivate = nullptr;
90
0
}
91
92
NS_IMETHODIMP
93
WorkerEventTarget::DispatchFromScript(nsIRunnable* aRunnable,
94
                                      uint32_t aFlags)
95
0
{
96
0
  nsCOMPtr<nsIRunnable> runnable(aRunnable);
97
0
  return Dispatch(runnable.forget(), aFlags);
98
0
}
99
100
NS_IMETHODIMP
101
WorkerEventTarget::Dispatch(already_AddRefed<nsIRunnable> aRunnable,
102
                            uint32_t aFlags)
103
0
{
104
0
  nsCOMPtr<nsIRunnable> runnable(aRunnable);
105
0
106
0
  MutexAutoLock lock(mMutex);
107
0
108
0
  if (!mWorkerPrivate) {
109
0
    return NS_ERROR_FAILURE;
110
0
  }
111
0
112
0
  if (mBehavior == Behavior::Hybrid) {
113
0
    RefPtr<WorkerRunnable> r =
114
0
      mWorkerPrivate->MaybeWrapAsWorkerRunnable(runnable.forget());
115
0
    if (r->Dispatch()) {
116
0
      return NS_OK;
117
0
    }
118
0
119
0
    runnable = r.forget();
120
0
  }
121
0
122
0
  RefPtr<WorkerControlRunnable> r =
123
0
    new WrappedControlRunnable(mWorkerPrivate, runnable.forget());
124
0
  if (!r->Dispatch()) {
125
0
    return NS_ERROR_FAILURE;
126
0
  }
127
0
128
0
  return NS_OK;
129
0
}
130
131
NS_IMETHODIMP
132
WorkerEventTarget::DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t)
133
0
{
134
0
  return NS_ERROR_NOT_IMPLEMENTED;
135
0
}
136
137
NS_IMETHODIMP_(bool)
138
WorkerEventTarget::IsOnCurrentThreadInfallible()
139
0
{
140
0
  MutexAutoLock lock(mMutex);
141
0
142
0
  if (!mWorkerPrivate) {
143
0
    return false;
144
0
  }
145
0
146
0
  return mWorkerPrivate->IsOnCurrentThread();
147
0
}
148
149
NS_IMETHODIMP
150
WorkerEventTarget::IsOnCurrentThread(bool* aIsOnCurrentThread)
151
0
{
152
0
  MOZ_ASSERT(aIsOnCurrentThread);
153
0
  *aIsOnCurrentThread = IsOnCurrentThreadInfallible();
154
0
  return NS_OK;
155
0
}
156
157
} // dom namespace
158
} // mozilla namespace