Bug 1890793: Assert CallArgs::newTarget is not gray. r=spidermonkey-reviewers,sfink...
[gecko.git] / xpcom / threads / LazyIdleThread.cpp
blob4187fcc4ff61b251a37ac90ef5b60585045e6b18
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/. */
7 #include "LazyIdleThread.h"
9 #include "nsIObserverService.h"
10 #include "nsServiceManagerUtils.h"
11 #include "nsThreadUtils.h"
13 #ifdef DEBUG
14 # define ASSERT_OWNING_THREAD() \
15 do { \
16 MOZ_ASSERT(mOwningEventTarget->IsOnCurrentThread()); \
17 } while (0)
18 #else
19 # define ASSERT_OWNING_THREAD() /* nothing */
20 #endif
22 namespace mozilla {
24 LazyIdleThread::LazyIdleThread(uint32_t aIdleTimeoutMS, const char* aName,
25 ShutdownMethod aShutdownMethod)
26 : mOwningEventTarget(GetCurrentSerialEventTarget()),
27 mThreadPool(new nsThreadPool()),
28 mTaskQueue(TaskQueue::Create(do_AddRef(mThreadPool), aName)) {
29 // Configure the threadpool to host a single thread. It will be responsible
30 // for managing the thread's lifetime.
31 MOZ_ALWAYS_SUCCEEDS(mThreadPool->SetThreadLimit(1));
32 MOZ_ALWAYS_SUCCEEDS(mThreadPool->SetIdleThreadLimit(1));
33 MOZ_ALWAYS_SUCCEEDS(mThreadPool->SetIdleThreadTimeout(aIdleTimeoutMS));
34 MOZ_ALWAYS_SUCCEEDS(mThreadPool->SetName(nsDependentCString(aName)));
36 if (aShutdownMethod == ShutdownMethod::AutomaticShutdown &&
37 NS_IsMainThread()) {
38 if (nsCOMPtr<nsIObserverService> obs =
39 do_GetService(NS_OBSERVERSERVICE_CONTRACTID)) {
40 MOZ_ALWAYS_SUCCEEDS(
41 obs->AddObserver(this, "xpcom-shutdown-threads", false));
46 static void LazyIdleThreadShutdown(nsThreadPool* aThreadPool,
47 TaskQueue* aTaskQueue) {
48 aTaskQueue->BeginShutdown();
49 aTaskQueue->AwaitShutdownAndIdle();
50 aThreadPool->Shutdown();
53 LazyIdleThread::~LazyIdleThread() {
54 if (!mShutdown) {
55 mOwningEventTarget->Dispatch(NS_NewRunnableFunction(
56 "LazyIdleThread::~LazyIdleThread",
57 [threadPool = mThreadPool, taskQueue = mTaskQueue] {
58 LazyIdleThreadShutdown(threadPool, taskQueue);
59 }));
63 void LazyIdleThread::Shutdown() {
64 ASSERT_OWNING_THREAD();
66 if (!mShutdown) {
67 mShutdown = true;
68 LazyIdleThreadShutdown(mThreadPool, mTaskQueue);
72 nsresult LazyIdleThread::SetListener(nsIThreadPoolListener* aListener) {
73 return mThreadPool->SetListener(aListener);
76 NS_IMPL_ISUPPORTS(LazyIdleThread, nsIEventTarget, nsISerialEventTarget,
77 nsIObserver)
79 NS_IMETHODIMP
80 LazyIdleThread::DispatchFromScript(nsIRunnable* aEvent, uint32_t aFlags) {
81 nsCOMPtr<nsIRunnable> event(aEvent);
82 return Dispatch(event.forget(), aFlags);
85 NS_IMETHODIMP
86 LazyIdleThread::Dispatch(already_AddRefed<nsIRunnable> aEvent,
87 uint32_t aFlags) {
88 return mTaskQueue->Dispatch(std::move(aEvent), aFlags);
91 NS_IMETHODIMP
92 LazyIdleThread::DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t) {
93 return NS_ERROR_NOT_IMPLEMENTED;
96 NS_IMETHODIMP
97 LazyIdleThread::RegisterShutdownTask(nsITargetShutdownTask* aTask) {
98 return NS_ERROR_NOT_IMPLEMENTED;
101 NS_IMETHODIMP
102 LazyIdleThread::UnregisterShutdownTask(nsITargetShutdownTask* aTask) {
103 return NS_ERROR_NOT_IMPLEMENTED;
106 NS_IMETHODIMP
107 LazyIdleThread::IsOnCurrentThread(bool* aIsOnCurrentThread) {
108 return mTaskQueue->IsOnCurrentThread(aIsOnCurrentThread);
111 NS_IMETHODIMP_(bool)
112 LazyIdleThread::IsOnCurrentThreadInfallible() {
113 return mTaskQueue->IsOnCurrentThreadInfallible();
116 NS_IMETHODIMP
117 LazyIdleThread::Observe(nsISupports* /* aSubject */, const char* aTopic,
118 const char16_t* /* aData */) {
119 MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
120 MOZ_ASSERT(!strcmp("xpcom-shutdown-threads", aTopic), "Bad topic!");
122 Shutdown();
123 return NS_OK;
126 } // namespace mozilla