Bug 1932613 - temporarily disable browser_ml_end_to_end.js for permanent failures...
[gecko.git] / xpcom / threads / LazyIdleThread.cpp
blobb24d3079ae981e931f8a2ccd6073118500a67074
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->SetIdleThreadGraceTimeout(0));
34 MOZ_ALWAYS_SUCCEEDS(mThreadPool->SetIdleThreadMaximumTimeout(aIdleTimeoutMS));
35 MOZ_ALWAYS_SUCCEEDS(mThreadPool->SetName(nsDependentCString(aName)));
37 if (aShutdownMethod == ShutdownMethod::AutomaticShutdown &&
38 NS_IsMainThread()) {
39 if (nsCOMPtr<nsIObserverService> obs =
40 do_GetService(NS_OBSERVERSERVICE_CONTRACTID)) {
41 MOZ_ALWAYS_SUCCEEDS(
42 obs->AddObserver(this, "xpcom-shutdown-threads", false));
47 static void LazyIdleThreadShutdown(nsThreadPool* aThreadPool,
48 TaskQueue* aTaskQueue) {
49 aTaskQueue->BeginShutdown();
50 aTaskQueue->AwaitShutdownAndIdle();
51 aThreadPool->Shutdown();
54 LazyIdleThread::~LazyIdleThread() {
55 if (!mShutdown) {
56 mOwningEventTarget->Dispatch(NS_NewRunnableFunction(
57 "LazyIdleThread::~LazyIdleThread",
58 [threadPool = mThreadPool, taskQueue = mTaskQueue] {
59 LazyIdleThreadShutdown(threadPool, taskQueue);
60 }));
64 void LazyIdleThread::Shutdown() {
65 ASSERT_OWNING_THREAD();
67 if (!mShutdown) {
68 mShutdown = true;
69 LazyIdleThreadShutdown(mThreadPool, mTaskQueue);
73 nsresult LazyIdleThread::SetListener(nsIThreadPoolListener* aListener) {
74 return mThreadPool->SetListener(aListener);
77 NS_IMPL_ISUPPORTS(LazyIdleThread, nsIEventTarget, nsISerialEventTarget,
78 nsIObserver)
80 NS_IMETHODIMP
81 LazyIdleThread::DispatchFromScript(nsIRunnable* aEvent, uint32_t aFlags) {
82 nsCOMPtr<nsIRunnable> event(aEvent);
83 return Dispatch(event.forget(), aFlags);
86 NS_IMETHODIMP
87 LazyIdleThread::Dispatch(already_AddRefed<nsIRunnable> aEvent,
88 uint32_t aFlags) {
89 return mTaskQueue->Dispatch(std::move(aEvent), aFlags);
92 NS_IMETHODIMP
93 LazyIdleThread::DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t) {
94 return NS_ERROR_NOT_IMPLEMENTED;
97 NS_IMETHODIMP
98 LazyIdleThread::RegisterShutdownTask(nsITargetShutdownTask* aTask) {
99 return NS_ERROR_NOT_IMPLEMENTED;
102 NS_IMETHODIMP
103 LazyIdleThread::UnregisterShutdownTask(nsITargetShutdownTask* aTask) {
104 return NS_ERROR_NOT_IMPLEMENTED;
107 NS_IMETHODIMP
108 LazyIdleThread::IsOnCurrentThread(bool* aIsOnCurrentThread) {
109 return mTaskQueue->IsOnCurrentThread(aIsOnCurrentThread);
112 NS_IMETHODIMP_(bool)
113 LazyIdleThread::IsOnCurrentThreadInfallible() {
114 return mTaskQueue->IsOnCurrentThreadInfallible();
117 NS_IMETHODIMP
118 LazyIdleThread::Observe(nsISupports* /* aSubject */, const char* aTopic,
119 const char16_t* /* aData */) {
120 MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
121 MOZ_ASSERT(!strcmp("xpcom-shutdown-threads", aTopic), "Bad topic!");
123 Shutdown();
124 return NS_OK;
127 } // namespace mozilla