summaryrefslogtreecommitdiffstats
path: root/dom/workers/WorkerThread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/workers/WorkerThread.cpp')
-rw-r--r--dom/workers/WorkerThread.cpp87
1 files changed, 45 insertions, 42 deletions
diff --git a/dom/workers/WorkerThread.cpp b/dom/workers/WorkerThread.cpp
index 14d944e4d3..2b051c0440 100644
--- a/dom/workers/WorkerThread.cpp
+++ b/dom/workers/WorkerThread.cpp
@@ -117,50 +117,54 @@ SafeRefPtr<WorkerThread> WorkerThread::Create(
void WorkerThread::SetWorker(const WorkerThreadFriendKey& /* aKey */,
WorkerPrivate* aWorkerPrivate) {
MOZ_ASSERT(PR_GetCurrentThread() == mThread);
+ MOZ_ASSERT(aWorkerPrivate);
- if (aWorkerPrivate) {
- {
- MutexAutoLock lock(mLock);
+ {
+ MutexAutoLock lock(mLock);
- MOZ_ASSERT(!mWorkerPrivate);
- MOZ_ASSERT(mAcceptingNonWorkerRunnables);
+ MOZ_ASSERT(!mWorkerPrivate);
+ MOZ_ASSERT(mAcceptingNonWorkerRunnables);
- mWorkerPrivate = aWorkerPrivate;
+ mWorkerPrivate = aWorkerPrivate;
#ifdef DEBUG
- mAcceptingNonWorkerRunnables = false;
+ mAcceptingNonWorkerRunnables = false;
#endif
- }
+ }
- mObserver = new Observer(aWorkerPrivate);
- MOZ_ALWAYS_SUCCEEDS(AddObserver(mObserver));
- } else {
- MOZ_ALWAYS_SUCCEEDS(RemoveObserver(mObserver));
- mObserver = nullptr;
+ mObserver = new Observer(aWorkerPrivate);
+ MOZ_ALWAYS_SUCCEEDS(AddObserver(mObserver));
+}
- {
- MutexAutoLock lock(mLock);
+void WorkerThread::ClearEventQueueAndWorker(
+ const WorkerThreadFriendKey& /* aKey */) {
+ MOZ_ASSERT(PR_GetCurrentThread() == mThread);
- MOZ_ASSERT(mWorkerPrivate);
- MOZ_ASSERT(!mAcceptingNonWorkerRunnables);
- // mOtherThreadsDispatchingViaEventTarget can still be non-zero here
- // because WorkerThread::Dispatch isn't atomic so a thread initiating
- // dispatch can have dispatched a runnable at this thread allowing us to
- // begin shutdown before that thread gets a chance to decrement
- // mOtherThreadsDispatchingViaEventTarget back to 0. So we need to wait
- // for that.
- while (mOtherThreadsDispatchingViaEventTarget) {
- mWorkerPrivateCondVar.Wait();
- }
- // Need to clean up the dispatched runnables if
- // mOtherThreadsDispatchingViaEventTarget was non-zero.
- if (NS_HasPendingEvents(nullptr)) {
- NS_ProcessPendingEvents(nullptr);
- }
+ MOZ_ALWAYS_SUCCEEDS(RemoveObserver(mObserver));
+ mObserver = nullptr;
+
+ {
+ MutexAutoLock lock(mLock);
+
+ MOZ_ASSERT(mWorkerPrivate);
+ MOZ_ASSERT(!mAcceptingNonWorkerRunnables);
+ // mOtherThreadsDispatchingViaEventTarget can still be non-zero here
+ // because WorkerThread::Dispatch isn't atomic so a thread initiating
+ // dispatch can have dispatched a runnable at this thread allowing us to
+ // begin shutdown before that thread gets a chance to decrement
+ // mOtherThreadsDispatchingViaEventTarget back to 0. So we need to wait
+ // for that.
+ while (mOtherThreadsDispatchingViaEventTarget) {
+ mWorkerPrivateCondVar.Wait();
+ }
+ // Need to clean up the dispatched runnables if
+ // mOtherThreadsDispatchingViaEventTarget was non-zero.
+ if (NS_HasPendingEvents(nullptr)) {
+ NS_ProcessPendingEvents(nullptr);
+ }
#ifdef DEBUG
- mAcceptingNonWorkerRunnables = true;
+ mAcceptingNonWorkerRunnables = true;
#endif
- mWorkerPrivate = nullptr;
- }
+ mWorkerPrivate = nullptr;
}
}
@@ -246,8 +250,13 @@ WorkerThread::Dispatch(already_AddRefed<nsIRunnable> aRunnable,
WorkerPrivate* workerPrivate = nullptr;
if (onWorkerThread) {
+ // If the mWorkerPrivate has already disconnected by
+ // WorkerPrivate::ResetWorkerPrivateInWorkerThread(), there is no chance
+ // that to execute this runnable. Return NS_ERROR_UNEXPECTED here.
+ if (!mWorkerPrivate) {
+ return NS_ERROR_UNEXPECTED;
+ }
// No need to lock here because it is only modified on this thread.
- MOZ_ASSERT(mWorkerPrivate);
mWorkerPrivate->AssertIsOnWorkerThread();
workerPrivate = mWorkerPrivate;
@@ -266,13 +275,7 @@ WorkerThread::Dispatch(already_AddRefed<nsIRunnable> aRunnable,
}
nsresult rv;
- if (runnable && onWorkerThread) {
- RefPtr<WorkerRunnable> workerRunnable =
- workerPrivate->MaybeWrapAsWorkerRunnable(runnable.forget());
- rv = nsThread::Dispatch(workerRunnable.forget(), NS_DISPATCH_NORMAL);
- } else {
- rv = nsThread::Dispatch(runnable.forget(), NS_DISPATCH_NORMAL);
- }
+ rv = nsThread::Dispatch(runnable.forget(), NS_DISPATCH_NORMAL);
if (!onWorkerThread && workerPrivate) {
// We need to wake the worker thread if we're not already on the right