• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #endif
22 
23 namespace base {
24 
25 namespace {
26 
27 #if DCHECK_IS_ON()
28 // Used to verify that the trace events used in the constructor do not result in
29 // instantiating a ScopedBlockingCall themselves (which would cause an infinite
30 // reentrancy loop).
31 constinit thread_local bool construction_in_progress = false;
32 #endif
33 
34 }  // namespace
35 
ScopedBlockingCall(const Location & from_here,BlockingType blocking_type)36 ScopedBlockingCall::ScopedBlockingCall(const Location& from_here,
37                                        BlockingType blocking_type)
38     : UncheckedScopedBlockingCall(
39           blocking_type,
40           UncheckedScopedBlockingCall::BlockingCallType::kRegular) {
41 #if DCHECK_IS_ON()
42   const AutoReset<bool> resetter(&construction_in_progress, true, false);
43 #endif
44 
45   AssertBlockingAllowed();
46   TRACE_EVENT_BEGIN(
47       "base", "ScopedBlockingCall", [&](perfetto::EventContext ctx) {
48         ctx.event()->set_source_location_iid(
49             base::trace_event::InternedSourceLocation::Get(&ctx, from_here));
50       });
51 }
52 
~ScopedBlockingCall()53 ScopedBlockingCall::~ScopedBlockingCall() {
54   TRACE_EVENT_END("base");
55 }
56 
57 namespace internal {
58 
59 ScopedBlockingCallWithBaseSyncPrimitives::
ScopedBlockingCallWithBaseSyncPrimitives(const Location & from_here,BlockingType blocking_type)60     ScopedBlockingCallWithBaseSyncPrimitives(const Location& from_here,
61                                              BlockingType blocking_type)
62     : UncheckedScopedBlockingCall(
63           blocking_type,
64           UncheckedScopedBlockingCall::BlockingCallType::kBaseSyncPrimitives) {
65 #if DCHECK_IS_ON()
66   const AutoReset<bool> resetter(&construction_in_progress, true, false);
67 #endif
68 
69   internal::AssertBaseSyncPrimitivesAllowed();
70   TRACE_EVENT_BEGIN(
71       "base", "ScopedBlockingCallWithBaseSyncPrimitives",
72       [&](perfetto::EventContext ctx) {
73         perfetto::protos::pbzero::SourceLocation* source_location_data =
74             ctx.event()->set_source_location();
75         source_location_data->set_file_name(from_here.file_name());
76         source_location_data->set_function_name(from_here.function_name());
77       });
78 }
79 
80 ScopedBlockingCallWithBaseSyncPrimitives::
~ScopedBlockingCallWithBaseSyncPrimitives()81     ~ScopedBlockingCallWithBaseSyncPrimitives() {
82   TRACE_EVENT_END("base");
83 }
84 
85 }  // namespace internal
86 
87 }  // namespace base
88