1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_CHECKED_SCOPE_H_
18 #define INCLUDE_PERFETTO_TRACING_INTERNAL_CHECKED_SCOPE_H_
19 
20 #include "perfetto/base/export.h"
21 #include "perfetto/base/logging.h"
22 
23 namespace perfetto {
24 namespace internal {
25 
26 #if PERFETTO_DCHECK_IS_ON()
27 
28 // Checker to ensure that despite multiple scopes being present, only the active
29 // one is being accessed. Rules:
30 // - Only an active scope can create inner scopes. When this happens, it stops
31 // being active and the inner scope becomes active instead.
32 // - Only an active scope can be destroyed. When this happens, its parent scope
33 // becomes active.
34 class PERFETTO_EXPORT CheckedScope {
35  public:
36   explicit CheckedScope(CheckedScope* parent_scope);
37   ~CheckedScope();
38   CheckedScope(CheckedScope&&);
39   CheckedScope& operator=(CheckedScope&&);
40   CheckedScope(const CheckedScope&) = delete;
41   CheckedScope& operator=(const CheckedScope&) = delete;
42 
43   void Reset();
44 
parent_scope()45   CheckedScope* parent_scope() const { return parent_scope_; }
is_active()46   bool is_active() const { return is_active_; }
47 
48  private:
set_is_active(bool is_active)49   void set_is_active(bool is_active) { is_active_ = is_active; }
50 
51   bool is_active_ = true;
52   CheckedScope* parent_scope_;
53 
54   bool deleted_ = false;
55 };
56 
57 #else
58 
59 // Dummy for cases when DCHECK is not enabled. Methods are marked constexpr to
60 // ensure that the compiler can inline and optimise them away.
61 class CheckedScope {
62  public:
63   inline explicit CheckedScope(CheckedScope*) {}
64   inline ~CheckedScope() {}
65 
66   inline void Reset() {}
67 
68   inline CheckedScope* parent_scope() const { return nullptr; }
69   inline bool is_active() const { return true; }
70 };
71 
72 #endif  // PERFETTO_DCHECK_IS_ON()
73 
74 }  // namespace internal
75 }  // namespace perfetto
76 
77 #endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_CHECKED_SCOPE_H_
78