forked from mirrors/gecko-dev
Once WorkerPrivate::ResetWorkerPrivateInWorkerThread() is called, the connection between the WorkerPrivate and the WorkerThread is decoupled. This means the WorkerPrivate is not valid anymore for any WorkerThreadRunnables. So, before decoupling the WorkerPrivate and WorkerThread, we should ensure all pending WorkerThreadRunnables are executed, and the Worker should be in the "Dead" status. It means the logic in the WorkerPrivate::RunLoopNeverRan() except WorkerPrivate::ScheduleDeletion() should be executed before WorkerPrivate::ResetWorkerPrivateInWorkerThread(). However, currently, these logic are executed after ResetWorkerPrivateInWorkerThread(). Differential Revision: https://phabricator.services.mozilla.com/D210775
115 lines
3.6 KiB
C++
115 lines
3.6 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/. */
|
|
|
|
#ifndef mozilla_dom_workers_WorkerThread_h__
|
|
#define mozilla_dom_workers_WorkerThread_h__
|
|
|
|
#include "mozilla/AlreadyAddRefed.h"
|
|
#include "mozilla/CondVar.h"
|
|
#include "mozilla/Mutex.h"
|
|
#include "mozilla/RefPtr.h"
|
|
#include "mozilla/dom/SafeRefPtr.h"
|
|
#include "nsISupports.h"
|
|
#include "nsThread.h"
|
|
#include "nscore.h"
|
|
|
|
class nsIRunnable;
|
|
|
|
namespace mozilla {
|
|
class Runnable;
|
|
|
|
namespace dom {
|
|
|
|
class WorkerRunnable;
|
|
class WorkerPrivate;
|
|
namespace workerinternals {
|
|
class RuntimeService;
|
|
}
|
|
|
|
// This class lets us restrict the public methods that can be called on
|
|
// WorkerThread to RuntimeService and WorkerPrivate without letting them gain
|
|
// full access to private methods (as would happen if they were simply friends).
|
|
class WorkerThreadFriendKey {
|
|
friend class workerinternals::RuntimeService;
|
|
friend class WorkerPrivate;
|
|
|
|
WorkerThreadFriendKey();
|
|
~WorkerThreadFriendKey();
|
|
};
|
|
|
|
class WorkerThread final : public nsThread {
|
|
class Observer;
|
|
|
|
Mutex mLock MOZ_UNANNOTATED;
|
|
CondVar mWorkerPrivateCondVar;
|
|
|
|
// Protected by nsThread::mLock.
|
|
WorkerPrivate* mWorkerPrivate;
|
|
|
|
// Only touched on the target thread.
|
|
RefPtr<Observer> mObserver;
|
|
|
|
// Protected by nsThread::mLock and waited on with mWorkerPrivateCondVar.
|
|
uint32_t mOtherThreadsDispatchingViaEventTarget;
|
|
|
|
#ifdef DEBUG
|
|
// Protected by nsThread::mLock.
|
|
bool mAcceptingNonWorkerRunnables;
|
|
#endif
|
|
|
|
// Using this struct we restrict access to the constructor while still being
|
|
// able to use MakeSafeRefPtr.
|
|
struct ConstructorKey {};
|
|
|
|
public:
|
|
explicit WorkerThread(ConstructorKey);
|
|
|
|
static SafeRefPtr<WorkerThread> Create(const WorkerThreadFriendKey& aKey);
|
|
|
|
void SetWorker(const WorkerThreadFriendKey& aKey,
|
|
WorkerPrivate* aWorkerPrivate);
|
|
|
|
// This method is used to decouple the connection with the WorkerPrivate which
|
|
// is set in SetWorker(). And it also clears all pending runnables on this
|
|
// WorkerThread.
|
|
// After decoupling, WorkerThreadRunnable can not run on this WorkerThread
|
|
// anymore, since WorkerPrivate is invalid.
|
|
void ClearEventQueueAndWorker(const WorkerThreadFriendKey& aKey);
|
|
|
|
nsresult DispatchPrimaryRunnable(const WorkerThreadFriendKey& aKey,
|
|
already_AddRefed<nsIRunnable> aRunnable);
|
|
|
|
nsresult DispatchAnyThread(const WorkerThreadFriendKey& aKey,
|
|
already_AddRefed<WorkerRunnable> aWorkerRunnable);
|
|
|
|
uint32_t RecursionDepth(const WorkerThreadFriendKey& aKey) const;
|
|
|
|
// Override HasPendingEvents to allow HasPendingEvents could be accessed by
|
|
// the parent thread. WorkerPrivate::IsEligibleForCC calls this method on the
|
|
// parent thread to check if there is any pending events on the worker thread.
|
|
NS_IMETHOD HasPendingEvents(bool* aHasPendingEvents) override;
|
|
|
|
NS_INLINE_DECL_REFCOUNTING_INHERITED(WorkerThread, nsThread)
|
|
|
|
private:
|
|
~WorkerThread();
|
|
|
|
// This should only be called by consumers that have an
|
|
// nsIEventTarget/nsIThread pointer.
|
|
NS_IMETHOD
|
|
Dispatch(already_AddRefed<nsIRunnable> aRunnable, uint32_t aFlags) override;
|
|
|
|
NS_IMETHOD
|
|
DispatchFromScript(nsIRunnable* aRunnable, uint32_t aFlags) override;
|
|
|
|
NS_IMETHOD
|
|
DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t) override;
|
|
};
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_dom_workers_WorkerThread_h__
|