xref: /aosp_15_r20/external/cronet/base/threading/scoped_blocking_call.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/threading/scoped_blocking_call.h"
6 
7 #include "base/lazy_instance.h"
8 #include "base/threading/thread_local.h"
9 #include "base/threading/thread_restrictions.h"
10 #include "base/time/time.h"
11 #include "base/trace_event/base_tracing.h"
12 #include "base/tracing_buildflags.h"
13 #include "build/build_config.h"
14 
15 #if BUILDFLAG(ENABLE_BASE_TRACING)
16 #include "third_party/perfetto/protos/perfetto/trace/track_event/source_location.pbzero.h"  // nogncheck
17 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
18 
19 #if DCHECK_IS_ON()
20 #include "base/auto_reset.h"
21 #include "third_party/abseil-cpp/absl/base/attributes.h"
22 #endif
23 
24 namespace base {
25 
26 namespace {
27 
28 #if DCHECK_IS_ON()
29 // Used to verify that the trace events used in the constructor do not result in
30 // instantiating a ScopedBlockingCall themselves (which would cause an infinite
31 // reentrancy loop).
32 ABSL_CONST_INIT thread_local bool construction_in_progress = false;
33 #endif
34 
35 }  // namespace
36 
ScopedBlockingCall(const Location & from_here,BlockingType blocking_type)37 ScopedBlockingCall::ScopedBlockingCall(const Location& from_here,
38                                        BlockingType blocking_type)
39     : UncheckedScopedBlockingCall(
40           blocking_type,
41           UncheckedScopedBlockingCall::BlockingCallType::kRegular) {
42 #if DCHECK_IS_ON()
43   const AutoReset<bool> resetter(&construction_in_progress, true, false);
44 #endif
45 
46   internal::AssertBlockingAllowed();
47   TRACE_EVENT_BEGIN(
48       "base", "ScopedBlockingCall", [&](perfetto::EventContext ctx) {
49         ctx.event()->set_source_location_iid(
50             base::trace_event::InternedSourceLocation::Get(&ctx, from_here));
51       });
52 }
53 
~ScopedBlockingCall()54 ScopedBlockingCall::~ScopedBlockingCall() {
55   TRACE_EVENT_END("base");
56 }
57 
58 namespace internal {
59 
60 ScopedBlockingCallWithBaseSyncPrimitives::
ScopedBlockingCallWithBaseSyncPrimitives(const Location & from_here,BlockingType blocking_type)61     ScopedBlockingCallWithBaseSyncPrimitives(const Location& from_here,
62                                              BlockingType blocking_type)
63     : UncheckedScopedBlockingCall(
64           blocking_type,
65           UncheckedScopedBlockingCall::BlockingCallType::kBaseSyncPrimitives) {
66 #if DCHECK_IS_ON()
67   const AutoReset<bool> resetter(&construction_in_progress, true, false);
68 #endif
69 
70   internal::AssertBaseSyncPrimitivesAllowed();
71   TRACE_EVENT_BEGIN(
72       "base", "ScopedBlockingCallWithBaseSyncPrimitives",
73       [&](perfetto::EventContext ctx) {
74         perfetto::protos::pbzero::SourceLocation* source_location_data =
75             ctx.event()->set_source_location();
76         source_location_data->set_file_name(from_here.file_name());
77         source_location_data->set_function_name(from_here.function_name());
78       });
79 }
80 
81 ScopedBlockingCallWithBaseSyncPrimitives::
~ScopedBlockingCallWithBaseSyncPrimitives()82     ~ScopedBlockingCallWithBaseSyncPrimitives() {
83   TRACE_EVENT_END("base");
84 }
85 
86 }  // namespace internal
87 
88 }  // namespace base
89