mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-13 01:55:44 +00:00
65e3d61d13
Differential Revision: https://phabricator.services.mozilla.com/D97170
140 lines
3.9 KiB
C++
140 lines
3.9 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "WorkerEventTarget.h"
|
|
#include "WorkerPrivate.h"
|
|
#include "WorkerRunnable.h"
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
|
|
namespace {
|
|
|
|
class WrappedControlRunnable final : public WorkerControlRunnable {
|
|
nsCOMPtr<nsIRunnable> mInner;
|
|
|
|
~WrappedControlRunnable() = default;
|
|
|
|
public:
|
|
WrappedControlRunnable(WorkerPrivate* aWorkerPrivate,
|
|
nsCOMPtr<nsIRunnable>&& aInner)
|
|
: WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount),
|
|
mInner(std::move(aInner)) {}
|
|
|
|
virtual bool PreDispatch(WorkerPrivate* aWorkerPrivate) override {
|
|
// Silence bad assertions, this can be dispatched from any thread.
|
|
return true;
|
|
}
|
|
|
|
virtual void PostDispatch(WorkerPrivate* aWorkerPrivate,
|
|
bool aDispatchResult) override {
|
|
// Silence bad assertions, this can be dispatched from any thread.
|
|
}
|
|
|
|
bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override {
|
|
mInner->Run();
|
|
return true;
|
|
}
|
|
|
|
nsresult Cancel() override {
|
|
nsCOMPtr<nsICancelableRunnable> cr = do_QueryInterface(mInner);
|
|
|
|
// If the inner runnable is not cancellable, then just do the normal
|
|
// WorkerControlRunnable thing. This will end up calling Run().
|
|
if (!cr) {
|
|
WorkerControlRunnable::Cancel();
|
|
return NS_OK;
|
|
}
|
|
|
|
// Otherwise call the inner runnable's Cancel() and treat this like
|
|
// a WorkerRunnable cancel. We can't call WorkerControlRunnable::Cancel()
|
|
// in this case since that would result in both Run() and the inner
|
|
// Cancel() being called.
|
|
Unused << cr->Cancel();
|
|
return WorkerRunnable::Cancel();
|
|
}
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
NS_IMPL_ISUPPORTS(WorkerEventTarget, nsIEventTarget, nsISerialEventTarget)
|
|
|
|
WorkerEventTarget::WorkerEventTarget(WorkerPrivate* aWorkerPrivate,
|
|
Behavior aBehavior)
|
|
: mMutex("WorkerEventTarget"),
|
|
mWorkerPrivate(aWorkerPrivate),
|
|
mBehavior(aBehavior) {
|
|
MOZ_DIAGNOSTIC_ASSERT(mWorkerPrivate);
|
|
}
|
|
|
|
void WorkerEventTarget::ForgetWorkerPrivate(WorkerPrivate* aWorkerPrivate) {
|
|
MutexAutoLock lock(mMutex);
|
|
MOZ_DIAGNOSTIC_ASSERT(!mWorkerPrivate || mWorkerPrivate == aWorkerPrivate);
|
|
mWorkerPrivate = nullptr;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
WorkerEventTarget::DispatchFromScript(nsIRunnable* aRunnable, uint32_t aFlags) {
|
|
nsCOMPtr<nsIRunnable> runnable(aRunnable);
|
|
return Dispatch(runnable.forget(), aFlags);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
WorkerEventTarget::Dispatch(already_AddRefed<nsIRunnable> aRunnable,
|
|
uint32_t aFlags) {
|
|
nsCOMPtr<nsIRunnable> runnable(aRunnable);
|
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
if (!mWorkerPrivate) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
if (mBehavior == Behavior::Hybrid) {
|
|
RefPtr<WorkerRunnable> r =
|
|
mWorkerPrivate->MaybeWrapAsWorkerRunnable(runnable.forget());
|
|
if (r->Dispatch()) {
|
|
return NS_OK;
|
|
}
|
|
|
|
runnable = std::move(r);
|
|
}
|
|
|
|
RefPtr<WorkerControlRunnable> r =
|
|
new WrappedControlRunnable(mWorkerPrivate, std::move(runnable));
|
|
if (!r->Dispatch()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
WorkerEventTarget::DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t) {
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP_(bool)
|
|
WorkerEventTarget::IsOnCurrentThreadInfallible() {
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
if (!mWorkerPrivate) {
|
|
return false;
|
|
}
|
|
|
|
return mWorkerPrivate->IsOnCurrentThread();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
WorkerEventTarget::IsOnCurrentThread(bool* aIsOnCurrentThread) {
|
|
MOZ_ASSERT(aIsOnCurrentThread);
|
|
*aIsOnCurrentThread = IsOnCurrentThreadInfallible();
|
|
return NS_OK;
|
|
}
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|