1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_restrictions.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include "base/threading/hang_watcher.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/base_tracing.h"
9*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
10*6777b538SAndroid Build Coastguard Worker
11*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
12*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
13*6777b538SAndroid Build Coastguard Worker #include "third_party/abseil-cpp/absl/base/attributes.h"
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard Worker // NaCL doesn't support stack sampling and Android is slow at stack sampling and
16*6777b538SAndroid Build Coastguard Worker // this causes timeouts (crbug.com/959139).
17*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_NACL) || BUILDFLAG(IS_ANDROID)
18*6777b538SAndroid Build Coastguard Worker constexpr bool kCaptureStackTraces = false;
19*6777b538SAndroid Build Coastguard Worker #else
20*6777b538SAndroid Build Coastguard Worker // Always disabled when !EXPENSIVE_DCHECKS_ARE_ON() because user-facing builds
21*6777b538SAndroid Build Coastguard Worker // typically drop log strings anyways.
22*6777b538SAndroid Build Coastguard Worker constexpr bool kCaptureStackTraces = EXPENSIVE_DCHECKS_ARE_ON();
23*6777b538SAndroid Build Coastguard Worker #endif
24*6777b538SAndroid Build Coastguard Worker
25*6777b538SAndroid Build Coastguard Worker namespace base {
26*6777b538SAndroid Build Coastguard Worker
BooleanWithStack(bool value)27*6777b538SAndroid Build Coastguard Worker BooleanWithStack::BooleanWithStack(bool value) : value_(value) {
28*6777b538SAndroid Build Coastguard Worker if (kCaptureStackTraces) {
29*6777b538SAndroid Build Coastguard Worker stack_.emplace();
30*6777b538SAndroid Build Coastguard Worker }
31*6777b538SAndroid Build Coastguard Worker }
32*6777b538SAndroid Build Coastguard Worker
operator <<(std::ostream & out,const BooleanWithStack & bws)33*6777b538SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& out, const BooleanWithStack& bws) {
34*6777b538SAndroid Build Coastguard Worker out << bws.value_;
35*6777b538SAndroid Build Coastguard Worker if (kCaptureStackTraces) {
36*6777b538SAndroid Build Coastguard Worker if (bws.stack_.has_value()) {
37*6777b538SAndroid Build Coastguard Worker out << " set by\n" << bws.stack_.value();
38*6777b538SAndroid Build Coastguard Worker } else {
39*6777b538SAndroid Build Coastguard Worker out << " (value by default)";
40*6777b538SAndroid Build Coastguard Worker }
41*6777b538SAndroid Build Coastguard Worker }
42*6777b538SAndroid Build Coastguard Worker return out;
43*6777b538SAndroid Build Coastguard Worker }
44*6777b538SAndroid Build Coastguard Worker
45*6777b538SAndroid Build Coastguard Worker namespace {
46*6777b538SAndroid Build Coastguard Worker
47*6777b538SAndroid Build Coastguard Worker ABSL_CONST_INIT thread_local BooleanWithStack tls_blocking_disallowed;
48*6777b538SAndroid Build Coastguard Worker ABSL_CONST_INIT thread_local BooleanWithStack tls_singleton_disallowed;
49*6777b538SAndroid Build Coastguard Worker ABSL_CONST_INIT thread_local BooleanWithStack
50*6777b538SAndroid Build Coastguard Worker tls_base_sync_primitives_disallowed;
51*6777b538SAndroid Build Coastguard Worker ABSL_CONST_INIT thread_local BooleanWithStack tls_cpu_intensive_work_disallowed;
52*6777b538SAndroid Build Coastguard Worker
53*6777b538SAndroid Build Coastguard Worker } // namespace
54*6777b538SAndroid Build Coastguard Worker
55*6777b538SAndroid Build Coastguard Worker namespace internal {
56*6777b538SAndroid Build Coastguard Worker
AssertBlockingAllowed()57*6777b538SAndroid Build Coastguard Worker void AssertBlockingAllowed() {
58*6777b538SAndroid Build Coastguard Worker DCHECK(!tls_blocking_disallowed)
59*6777b538SAndroid Build Coastguard Worker << "Function marked as blocking was called from a scope that disallows "
60*6777b538SAndroid Build Coastguard Worker "blocking! If this task is running inside the ThreadPool, it needs "
61*6777b538SAndroid Build Coastguard Worker "to have MayBlock() in its TaskTraits. Otherwise, consider making "
62*6777b538SAndroid Build Coastguard Worker "this blocking work asynchronous or, as a last resort, you may use "
63*6777b538SAndroid Build Coastguard Worker "ScopedAllowBlocking (see its documentation for best practices).\n"
64*6777b538SAndroid Build Coastguard Worker << "tls_blocking_disallowed " << tls_blocking_disallowed;
65*6777b538SAndroid Build Coastguard Worker }
66*6777b538SAndroid Build Coastguard Worker
AssertBlockingDisallowedForTesting()67*6777b538SAndroid Build Coastguard Worker void AssertBlockingDisallowedForTesting() {
68*6777b538SAndroid Build Coastguard Worker DCHECK(tls_blocking_disallowed)
69*6777b538SAndroid Build Coastguard Worker << "tls_blocking_disallowed " << tls_blocking_disallowed;
70*6777b538SAndroid Build Coastguard Worker }
71*6777b538SAndroid Build Coastguard Worker
72*6777b538SAndroid Build Coastguard Worker } // namespace internal
73*6777b538SAndroid Build Coastguard Worker
DisallowBlocking()74*6777b538SAndroid Build Coastguard Worker void DisallowBlocking() {
75*6777b538SAndroid Build Coastguard Worker tls_blocking_disallowed = BooleanWithStack(true);
76*6777b538SAndroid Build Coastguard Worker }
77*6777b538SAndroid Build Coastguard Worker
ScopedDisallowBlocking()78*6777b538SAndroid Build Coastguard Worker ScopedDisallowBlocking::ScopedDisallowBlocking()
79*6777b538SAndroid Build Coastguard Worker : resetter_(&tls_blocking_disallowed, BooleanWithStack(true)) {}
80*6777b538SAndroid Build Coastguard Worker
~ScopedDisallowBlocking()81*6777b538SAndroid Build Coastguard Worker ScopedDisallowBlocking::~ScopedDisallowBlocking() {
82*6777b538SAndroid Build Coastguard Worker DCHECK(tls_blocking_disallowed)
83*6777b538SAndroid Build Coastguard Worker << "~ScopedDisallowBlocking() running while surprisingly already no "
84*6777b538SAndroid Build Coastguard Worker "longer disallowed.\n"
85*6777b538SAndroid Build Coastguard Worker << "tls_blocking_disallowed " << tls_blocking_disallowed;
86*6777b538SAndroid Build Coastguard Worker }
87*6777b538SAndroid Build Coastguard Worker
DisallowBaseSyncPrimitives()88*6777b538SAndroid Build Coastguard Worker void DisallowBaseSyncPrimitives() {
89*6777b538SAndroid Build Coastguard Worker tls_base_sync_primitives_disallowed = BooleanWithStack(true);
90*6777b538SAndroid Build Coastguard Worker }
91*6777b538SAndroid Build Coastguard Worker
ScopedDisallowBaseSyncPrimitives()92*6777b538SAndroid Build Coastguard Worker ScopedDisallowBaseSyncPrimitives::ScopedDisallowBaseSyncPrimitives()
93*6777b538SAndroid Build Coastguard Worker : resetter_(&tls_base_sync_primitives_disallowed, BooleanWithStack(true)) {}
94*6777b538SAndroid Build Coastguard Worker
~ScopedDisallowBaseSyncPrimitives()95*6777b538SAndroid Build Coastguard Worker ScopedDisallowBaseSyncPrimitives::~ScopedDisallowBaseSyncPrimitives() {
96*6777b538SAndroid Build Coastguard Worker DCHECK(tls_base_sync_primitives_disallowed)
97*6777b538SAndroid Build Coastguard Worker << "~ScopedDisallowBaseSyncPrimitives() running while surprisingly "
98*6777b538SAndroid Build Coastguard Worker "already no longer disallowed.\n"
99*6777b538SAndroid Build Coastguard Worker << "tls_base_sync_primitives_disallowed "
100*6777b538SAndroid Build Coastguard Worker << tls_base_sync_primitives_disallowed;
101*6777b538SAndroid Build Coastguard Worker }
102*6777b538SAndroid Build Coastguard Worker
ScopedAllowBaseSyncPrimitives()103*6777b538SAndroid Build Coastguard Worker ScopedAllowBaseSyncPrimitives::ScopedAllowBaseSyncPrimitives()
104*6777b538SAndroid Build Coastguard Worker : resetter_(&tls_base_sync_primitives_disallowed, BooleanWithStack(false)) {
105*6777b538SAndroid Build Coastguard Worker DCHECK(!tls_blocking_disallowed)
106*6777b538SAndroid Build Coastguard Worker << "To allow //base sync primitives in a scope where blocking is "
107*6777b538SAndroid Build Coastguard Worker "disallowed use ScopedAllowBaseSyncPrimitivesOutsideBlockingScope.\n"
108*6777b538SAndroid Build Coastguard Worker << "tls_blocking_disallowed " << tls_blocking_disallowed;
109*6777b538SAndroid Build Coastguard Worker }
110*6777b538SAndroid Build Coastguard Worker
~ScopedAllowBaseSyncPrimitives()111*6777b538SAndroid Build Coastguard Worker ScopedAllowBaseSyncPrimitives::~ScopedAllowBaseSyncPrimitives() {
112*6777b538SAndroid Build Coastguard Worker DCHECK(!tls_base_sync_primitives_disallowed)
113*6777b538SAndroid Build Coastguard Worker << "~ScopedAllowBaseSyncPrimitives() running while surprisingly already "
114*6777b538SAndroid Build Coastguard Worker "no longer allowed.\n"
115*6777b538SAndroid Build Coastguard Worker << "tls_base_sync_primitives_disallowed "
116*6777b538SAndroid Build Coastguard Worker << tls_base_sync_primitives_disallowed;
117*6777b538SAndroid Build Coastguard Worker }
118*6777b538SAndroid Build Coastguard Worker
119*6777b538SAndroid Build Coastguard Worker ScopedAllowBaseSyncPrimitivesForTesting::
ScopedAllowBaseSyncPrimitivesForTesting()120*6777b538SAndroid Build Coastguard Worker ScopedAllowBaseSyncPrimitivesForTesting()
121*6777b538SAndroid Build Coastguard Worker : resetter_(&tls_base_sync_primitives_disallowed, BooleanWithStack(false)) {
122*6777b538SAndroid Build Coastguard Worker }
123*6777b538SAndroid Build Coastguard Worker
124*6777b538SAndroid Build Coastguard Worker ScopedAllowBaseSyncPrimitivesForTesting::
~ScopedAllowBaseSyncPrimitivesForTesting()125*6777b538SAndroid Build Coastguard Worker ~ScopedAllowBaseSyncPrimitivesForTesting() {
126*6777b538SAndroid Build Coastguard Worker DCHECK(!tls_base_sync_primitives_disallowed)
127*6777b538SAndroid Build Coastguard Worker << "~ScopedAllowBaseSyncPrimitivesForTesting() running while " // IN-TEST
128*6777b538SAndroid Build Coastguard Worker "surprisingly already no longer allowed.\n"
129*6777b538SAndroid Build Coastguard Worker << "tls_base_sync_primitives_disallowed "
130*6777b538SAndroid Build Coastguard Worker << tls_base_sync_primitives_disallowed;
131*6777b538SAndroid Build Coastguard Worker }
132*6777b538SAndroid Build Coastguard Worker
ScopedAllowUnresponsiveTasksForTesting()133*6777b538SAndroid Build Coastguard Worker ScopedAllowUnresponsiveTasksForTesting::ScopedAllowUnresponsiveTasksForTesting()
134*6777b538SAndroid Build Coastguard Worker : base_sync_resetter_(&tls_base_sync_primitives_disallowed,
135*6777b538SAndroid Build Coastguard Worker BooleanWithStack(false)),
136*6777b538SAndroid Build Coastguard Worker blocking_resetter_(&tls_blocking_disallowed, BooleanWithStack(false)),
137*6777b538SAndroid Build Coastguard Worker cpu_resetter_(&tls_cpu_intensive_work_disallowed,
138*6777b538SAndroid Build Coastguard Worker BooleanWithStack(false)) {}
139*6777b538SAndroid Build Coastguard Worker
140*6777b538SAndroid Build Coastguard Worker ScopedAllowUnresponsiveTasksForTesting::
~ScopedAllowUnresponsiveTasksForTesting()141*6777b538SAndroid Build Coastguard Worker ~ScopedAllowUnresponsiveTasksForTesting() {
142*6777b538SAndroid Build Coastguard Worker DCHECK(!tls_base_sync_primitives_disallowed)
143*6777b538SAndroid Build Coastguard Worker << "~ScopedAllowUnresponsiveTasksForTesting() running while " // IN-TEST
144*6777b538SAndroid Build Coastguard Worker "surprisingly already no longer allowed.\n"
145*6777b538SAndroid Build Coastguard Worker << "tls_base_sync_primitives_disallowed "
146*6777b538SAndroid Build Coastguard Worker << tls_base_sync_primitives_disallowed;
147*6777b538SAndroid Build Coastguard Worker DCHECK(!tls_blocking_disallowed)
148*6777b538SAndroid Build Coastguard Worker << "~ScopedAllowUnresponsiveTasksForTesting() running while " // IN-TEST
149*6777b538SAndroid Build Coastguard Worker "surprisingly already no longer allowed.\n"
150*6777b538SAndroid Build Coastguard Worker << "tls_blocking_disallowed " << tls_blocking_disallowed;
151*6777b538SAndroid Build Coastguard Worker DCHECK(!tls_cpu_intensive_work_disallowed)
152*6777b538SAndroid Build Coastguard Worker << "~ScopedAllowUnresponsiveTasksForTesting() running while " // IN-TEST
153*6777b538SAndroid Build Coastguard Worker "surprisingly already no longer allowed.\n"
154*6777b538SAndroid Build Coastguard Worker << "tls_cpu_intensive_work_disallowed "
155*6777b538SAndroid Build Coastguard Worker << tls_cpu_intensive_work_disallowed;
156*6777b538SAndroid Build Coastguard Worker }
157*6777b538SAndroid Build Coastguard Worker
158*6777b538SAndroid Build Coastguard Worker namespace internal {
159*6777b538SAndroid Build Coastguard Worker
AssertBaseSyncPrimitivesAllowed()160*6777b538SAndroid Build Coastguard Worker void AssertBaseSyncPrimitivesAllowed() {
161*6777b538SAndroid Build Coastguard Worker DCHECK(!tls_base_sync_primitives_disallowed)
162*6777b538SAndroid Build Coastguard Worker << "Waiting on a //base sync primitive is not allowed on this thread to "
163*6777b538SAndroid Build Coastguard Worker "prevent jank and deadlock. If waiting on a //base sync primitive is "
164*6777b538SAndroid Build Coastguard Worker "unavoidable, do it within the scope of a "
165*6777b538SAndroid Build Coastguard Worker "ScopedAllowBaseSyncPrimitives. If in a test, use "
166*6777b538SAndroid Build Coastguard Worker "ScopedAllowBaseSyncPrimitivesForTesting.\n"
167*6777b538SAndroid Build Coastguard Worker << "tls_base_sync_primitives_disallowed "
168*6777b538SAndroid Build Coastguard Worker << tls_base_sync_primitives_disallowed
169*6777b538SAndroid Build Coastguard Worker << "It can be useful to know that tls_blocking_disallowed is "
170*6777b538SAndroid Build Coastguard Worker << tls_blocking_disallowed;
171*6777b538SAndroid Build Coastguard Worker }
172*6777b538SAndroid Build Coastguard Worker
ResetThreadRestrictionsForTesting()173*6777b538SAndroid Build Coastguard Worker void ResetThreadRestrictionsForTesting() {
174*6777b538SAndroid Build Coastguard Worker tls_blocking_disallowed = BooleanWithStack(false);
175*6777b538SAndroid Build Coastguard Worker tls_singleton_disallowed = BooleanWithStack(false);
176*6777b538SAndroid Build Coastguard Worker tls_base_sync_primitives_disallowed = BooleanWithStack(false);
177*6777b538SAndroid Build Coastguard Worker tls_cpu_intensive_work_disallowed = BooleanWithStack(false);
178*6777b538SAndroid Build Coastguard Worker }
179*6777b538SAndroid Build Coastguard Worker
AssertSingletonAllowed()180*6777b538SAndroid Build Coastguard Worker void AssertSingletonAllowed() {
181*6777b538SAndroid Build Coastguard Worker DCHECK(!tls_singleton_disallowed)
182*6777b538SAndroid Build Coastguard Worker << "LazyInstance/Singleton is not allowed to be used on this thread. "
183*6777b538SAndroid Build Coastguard Worker "Most likely it's because this thread is not joinable (or the current "
184*6777b538SAndroid Build Coastguard Worker "task is running with TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN "
185*6777b538SAndroid Build Coastguard Worker "semantics), so AtExitManager may have deleted the object on "
186*6777b538SAndroid Build Coastguard Worker "shutdown, leading to a potential shutdown crash. If you need to use "
187*6777b538SAndroid Build Coastguard Worker "the object from this context, it'll have to be updated to use Leaky "
188*6777b538SAndroid Build Coastguard Worker "traits.\n"
189*6777b538SAndroid Build Coastguard Worker << "tls_singleton_disallowed " << tls_singleton_disallowed;
190*6777b538SAndroid Build Coastguard Worker }
191*6777b538SAndroid Build Coastguard Worker
192*6777b538SAndroid Build Coastguard Worker } // namespace internal
193*6777b538SAndroid Build Coastguard Worker
DisallowSingleton()194*6777b538SAndroid Build Coastguard Worker void DisallowSingleton() {
195*6777b538SAndroid Build Coastguard Worker tls_singleton_disallowed = BooleanWithStack(true);
196*6777b538SAndroid Build Coastguard Worker }
197*6777b538SAndroid Build Coastguard Worker
ScopedDisallowSingleton()198*6777b538SAndroid Build Coastguard Worker ScopedDisallowSingleton::ScopedDisallowSingleton()
199*6777b538SAndroid Build Coastguard Worker : resetter_(&tls_singleton_disallowed, BooleanWithStack(true)) {}
200*6777b538SAndroid Build Coastguard Worker
~ScopedDisallowSingleton()201*6777b538SAndroid Build Coastguard Worker ScopedDisallowSingleton::~ScopedDisallowSingleton() {
202*6777b538SAndroid Build Coastguard Worker DCHECK(tls_singleton_disallowed)
203*6777b538SAndroid Build Coastguard Worker << "~ScopedDisallowSingleton() running while surprisingly already no "
204*6777b538SAndroid Build Coastguard Worker "longer disallowed.\n"
205*6777b538SAndroid Build Coastguard Worker << "tls_singleton_disallowed " << tls_singleton_disallowed;
206*6777b538SAndroid Build Coastguard Worker }
207*6777b538SAndroid Build Coastguard Worker
AssertLongCPUWorkAllowed()208*6777b538SAndroid Build Coastguard Worker void AssertLongCPUWorkAllowed() {
209*6777b538SAndroid Build Coastguard Worker DCHECK(!tls_cpu_intensive_work_disallowed)
210*6777b538SAndroid Build Coastguard Worker << "Function marked as CPU intensive was called from a scope that "
211*6777b538SAndroid Build Coastguard Worker "disallows this kind of work! Consider making this work "
212*6777b538SAndroid Build Coastguard Worker "asynchronous.\n"
213*6777b538SAndroid Build Coastguard Worker << "tls_cpu_intensive_work_disallowed "
214*6777b538SAndroid Build Coastguard Worker << tls_cpu_intensive_work_disallowed;
215*6777b538SAndroid Build Coastguard Worker }
216*6777b538SAndroid Build Coastguard Worker
DisallowUnresponsiveTasks()217*6777b538SAndroid Build Coastguard Worker void DisallowUnresponsiveTasks() {
218*6777b538SAndroid Build Coastguard Worker DisallowBlocking();
219*6777b538SAndroid Build Coastguard Worker DisallowBaseSyncPrimitives();
220*6777b538SAndroid Build Coastguard Worker tls_cpu_intensive_work_disallowed = BooleanWithStack(true);
221*6777b538SAndroid Build Coastguard Worker }
222*6777b538SAndroid Build Coastguard Worker
223*6777b538SAndroid Build Coastguard Worker // static
AllowBlocking()224*6777b538SAndroid Build Coastguard Worker void PermanentThreadAllowance::AllowBlocking() {
225*6777b538SAndroid Build Coastguard Worker tls_blocking_disallowed = BooleanWithStack(false);
226*6777b538SAndroid Build Coastguard Worker }
227*6777b538SAndroid Build Coastguard Worker
228*6777b538SAndroid Build Coastguard Worker // static
AllowBaseSyncPrimitives()229*6777b538SAndroid Build Coastguard Worker void PermanentThreadAllowance::AllowBaseSyncPrimitives() {
230*6777b538SAndroid Build Coastguard Worker tls_base_sync_primitives_disallowed = BooleanWithStack(false);
231*6777b538SAndroid Build Coastguard Worker }
232*6777b538SAndroid Build Coastguard Worker
233*6777b538SAndroid Build Coastguard Worker } // namespace base
234*6777b538SAndroid Build Coastguard Worker
235*6777b538SAndroid Build Coastguard Worker #endif // DCHECK_IS_ON()
236*6777b538SAndroid Build Coastguard Worker
237*6777b538SAndroid Build Coastguard Worker namespace base {
238*6777b538SAndroid Build Coastguard Worker
ScopedAllowBlocking(const Location & from_here)239*6777b538SAndroid Build Coastguard Worker ScopedAllowBlocking::ScopedAllowBlocking(const Location& from_here)
240*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
241*6777b538SAndroid Build Coastguard Worker : resetter_(&tls_blocking_disallowed, BooleanWithStack(false))
242*6777b538SAndroid Build Coastguard Worker #endif
243*6777b538SAndroid Build Coastguard Worker {
244*6777b538SAndroid Build Coastguard Worker TRACE_EVENT_BEGIN(
245*6777b538SAndroid Build Coastguard Worker "base", "ScopedAllowBlocking", [&](perfetto::EventContext ctx) {
246*6777b538SAndroid Build Coastguard Worker ctx.event()->set_source_location_iid(
247*6777b538SAndroid Build Coastguard Worker base::trace_event::InternedSourceLocation::Get(&ctx, from_here));
248*6777b538SAndroid Build Coastguard Worker });
249*6777b538SAndroid Build Coastguard Worker }
250*6777b538SAndroid Build Coastguard Worker
~ScopedAllowBlocking()251*6777b538SAndroid Build Coastguard Worker ScopedAllowBlocking::~ScopedAllowBlocking() {
252*6777b538SAndroid Build Coastguard Worker TRACE_EVENT_END0("base", "ScopedAllowBlocking");
253*6777b538SAndroid Build Coastguard Worker
254*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
255*6777b538SAndroid Build Coastguard Worker DCHECK(!tls_blocking_disallowed)
256*6777b538SAndroid Build Coastguard Worker << "~ScopedAllowBlocking() running while surprisingly already no longer "
257*6777b538SAndroid Build Coastguard Worker "allowed.\n"
258*6777b538SAndroid Build Coastguard Worker << "tls_blocking_disallowed " << tls_blocking_disallowed;
259*6777b538SAndroid Build Coastguard Worker #endif
260*6777b538SAndroid Build Coastguard Worker }
261*6777b538SAndroid Build Coastguard Worker
262*6777b538SAndroid Build Coastguard Worker ScopedAllowBaseSyncPrimitivesOutsideBlockingScope::
ScopedAllowBaseSyncPrimitivesOutsideBlockingScope(const Location & from_here)263*6777b538SAndroid Build Coastguard Worker ScopedAllowBaseSyncPrimitivesOutsideBlockingScope(const Location& from_here)
264*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
265*6777b538SAndroid Build Coastguard Worker : resetter_(&tls_base_sync_primitives_disallowed, BooleanWithStack(false))
266*6777b538SAndroid Build Coastguard Worker #endif
267*6777b538SAndroid Build Coastguard Worker {
268*6777b538SAndroid Build Coastguard Worker TRACE_EVENT_BEGIN(
269*6777b538SAndroid Build Coastguard Worker "base", "ScopedAllowBaseSyncPrimitivesOutsideBlockingScope",
270*6777b538SAndroid Build Coastguard Worker [&](perfetto::EventContext ctx) {
271*6777b538SAndroid Build Coastguard Worker ctx.event()->set_source_location_iid(
272*6777b538SAndroid Build Coastguard Worker base::trace_event::InternedSourceLocation::Get(&ctx, from_here));
273*6777b538SAndroid Build Coastguard Worker });
274*6777b538SAndroid Build Coastguard Worker
275*6777b538SAndroid Build Coastguard Worker // Since this object is used to indicate that sync primitives will be used to
276*6777b538SAndroid Build Coastguard Worker // wait for an event ignore the current operation for hang watching purposes
277*6777b538SAndroid Build Coastguard Worker // since the wait time duration is unknown.
278*6777b538SAndroid Build Coastguard Worker base::HangWatcher::InvalidateActiveExpectations();
279*6777b538SAndroid Build Coastguard Worker }
280*6777b538SAndroid Build Coastguard Worker
281*6777b538SAndroid Build Coastguard Worker ScopedAllowBaseSyncPrimitivesOutsideBlockingScope::
~ScopedAllowBaseSyncPrimitivesOutsideBlockingScope()282*6777b538SAndroid Build Coastguard Worker ~ScopedAllowBaseSyncPrimitivesOutsideBlockingScope() {
283*6777b538SAndroid Build Coastguard Worker TRACE_EVENT_END0("base", "ScopedAllowBaseSyncPrimitivesOutsideBlockingScope");
284*6777b538SAndroid Build Coastguard Worker
285*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
286*6777b538SAndroid Build Coastguard Worker DCHECK(!tls_base_sync_primitives_disallowed)
287*6777b538SAndroid Build Coastguard Worker << "~ScopedAllowBaseSyncPrimitivesOutsideBlockingScope() running while "
288*6777b538SAndroid Build Coastguard Worker "surprisingly already no longer allowed.\n"
289*6777b538SAndroid Build Coastguard Worker << "tls_base_sync_primitives_disallowed "
290*6777b538SAndroid Build Coastguard Worker << tls_base_sync_primitives_disallowed;
291*6777b538SAndroid Build Coastguard Worker #endif
292*6777b538SAndroid Build Coastguard Worker }
293*6777b538SAndroid Build Coastguard Worker
294*6777b538SAndroid Build Coastguard Worker } // namespace base
295