nsresult TaskQueue::DispatchLocked(already_AddRefed<nsIRunnable> aRunnable, DispatchMode aMode, DispatchFailureHandling aFailureHandling, DispatchReason aReason) { nsCOMPtr<nsIRunnable> r = aRunnable; AbstractThread* currentThread; if (aReason != TailDispatch && (currentThread = GetCurrent()) && RequiresTailDispatch(currentThread)) { currentThread->TailDispatcher().AddTask(this, r.forget(), aFailureHandling); return NS_OK; } mQueueMonitor.AssertCurrentThreadOwns(); if (mIsFlushing && aMode == AbortIfFlushing) { return NS_ERROR_ABORT; } if (mIsShutdown) { return NS_ERROR_FAILURE; } mTasks.push(r.forget()); if (mIsRunning) { return NS_OK; } nsRefPtr<nsIRunnable> runner(new Runner(this)); nsresult rv = mPool->Dispatch(runner.forget(), NS_DISPATCH_NORMAL); if (NS_FAILED(rv)) { NS_WARNING("Failed to dispatch runnable to run TaskQueue"); return rv; } mIsRunning = true; return NS_OK; }
virtual void Dispatch(already_AddRefed<nsIRunnable> aRunnable, DispatchFailureHandling aFailureHandling = AssertDispatchSuccess, DispatchReason aReason = NormalDispatch) override { nsCOMPtr<nsIRunnable> r = aRunnable; AbstractThread* currentThread; if (aReason != TailDispatch && (currentThread = GetCurrent()) && RequiresTailDispatch(currentThread)) { currentThread->TailDispatcher().AddTask(this, r.forget(), aFailureHandling); return; } nsresult rv = mTarget->Dispatch(r, NS_DISPATCH_NORMAL); MOZ_DIAGNOSTIC_ASSERT(aFailureHandling == DontAssertDispatchSuccess || NS_SUCCEEDED(rv)); unused << rv; }
bool AbstractThread::RequiresTailDispatchFromCurrentThread() const { AbstractThread* current = GetCurrent(); return current && RequiresTailDispatch(current); }