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 "mozilla/SchedulerGroup.h"
11 #include "jsfriendapi.h"
12 #include "mozilla/Atomics.h"
13 #include "mozilla/Telemetry.h"
14 #include "mozilla/Unused.h"
15 #include "mozilla/dom/DocGroup.h"
16 #include "mozilla/dom/ScriptSettings.h"
18 #include "nsQueryObject.h"
19 #include "nsThreadUtils.h"
21 using namespace mozilla
;
24 nsresult
SchedulerGroup::UnlabeledDispatch(
25 TaskCategory aCategory
, already_AddRefed
<nsIRunnable
>&& aRunnable
) {
26 if (NS_IsMainThread()) {
27 return NS_DispatchToCurrentThread(std::move(aRunnable
));
29 return NS_DispatchToMainThread(std::move(aRunnable
));
34 nsresult
SchedulerGroup::Dispatch(TaskCategory aCategory
,
35 already_AddRefed
<nsIRunnable
>&& aRunnable
) {
36 return LabeledDispatch(aCategory
, std::move(aRunnable
), nullptr);
40 nsresult
SchedulerGroup::LabeledDispatch(
41 TaskCategory aCategory
, already_AddRefed
<nsIRunnable
>&& aRunnable
,
42 mozilla::PerformanceCounter
* aPerformanceCounter
) {
43 nsCOMPtr
<nsIRunnable
> runnable(aRunnable
);
44 if (XRE_IsContentProcess()) {
45 RefPtr
<Runnable
> internalRunnable
=
46 new Runnable(runnable
.forget(), aPerformanceCounter
);
47 return InternalUnlabeledDispatch(aCategory
, internalRunnable
.forget());
49 return UnlabeledDispatch(aCategory
, runnable
.forget());
53 nsresult
SchedulerGroup::InternalUnlabeledDispatch(
54 TaskCategory aCategory
, already_AddRefed
<Runnable
>&& aRunnable
) {
55 if (NS_IsMainThread()) {
56 // NS_DispatchToCurrentThread will not leak the passed in runnable
57 // when it fails, so we don't need to do anything special.
58 return NS_DispatchToCurrentThread(std::move(aRunnable
));
61 RefPtr
<Runnable
> runnable(aRunnable
);
62 nsresult rv
= NS_DispatchToMainThread(do_AddRef(runnable
));
64 // Dispatch failed. This is a situation where we would have used
65 // NS_DispatchToMainThread rather than calling into the SchedulerGroup
66 // machinery, and the caller would be expecting to leak the nsIRunnable
67 // originally passed in. But because we've had to wrap things up
68 // internally, we were going to leak the nsIRunnable *and* our Runnable
69 // wrapper. But there's no reason that we have to leak our Runnable
70 // wrapper; we can just leak the wrapped nsIRunnable, and let the caller
71 // take care of unleaking it if they need to.
72 Unused
<< runnable
->mRunnable
.forget().take();
73 nsrefcnt refcnt
= runnable
.get()->Release();
74 MOZ_RELEASE_ASSERT(refcnt
== 1, "still holding an unexpected reference!");
80 SchedulerGroup::Runnable::Runnable(
81 already_AddRefed
<nsIRunnable
>&& aRunnable
,
82 mozilla::PerformanceCounter
* aPerformanceCounter
)
83 : mozilla::Runnable("SchedulerGroup::Runnable"),
84 mRunnable(std::move(aRunnable
)),
85 mPerformanceCounter(aPerformanceCounter
) {}
87 mozilla::PerformanceCounter
* SchedulerGroup::Runnable::GetPerformanceCounter()
89 return mPerformanceCounter
;
92 #ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
94 SchedulerGroup::Runnable::GetName(nsACString
& aName
) {
95 // Try to get a name from the underlying runnable.
96 nsCOMPtr
<nsINamed
> named
= do_QueryInterface(mRunnable
);
98 named
->GetName(aName
);
100 if (aName
.IsEmpty()) {
101 aName
.AssignLiteral("anonymous");
109 SchedulerGroup::Runnable::Run() {
110 MOZ_RELEASE_ASSERT(NS_IsMainThread());
111 // The runnable's destructor can have side effects, so try to execute it in
112 // the scope of the SchedulerGroup.
113 nsCOMPtr
<nsIRunnable
> runnable(std::move(mRunnable
));
114 return runnable
->Run();
118 SchedulerGroup::Runnable::GetPriority(uint32_t* aPriority
) {
119 *aPriority
= nsIRunnablePriority::PRIORITY_NORMAL
;
120 nsCOMPtr
<nsIRunnablePriority
> runnablePrio
= do_QueryInterface(mRunnable
);
121 return runnablePrio
? runnablePrio
->GetPriority(aPriority
) : NS_OK
;
124 NS_IMPL_ISUPPORTS_INHERITED(SchedulerGroup::Runnable
, mozilla::Runnable
,
125 nsIRunnablePriority
, SchedulerGroup::Runnable
)