/src/mozilla-central/security/sandbox/chromium/base/callback_internal.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 | | // Use of this source code is governed by a BSD-style license that can be |
3 | | // found in the LICENSE file. |
4 | | |
5 | | // This file contains utility functions and classes that help the |
6 | | // implementation, and management of the Callback objects. |
7 | | |
8 | | #ifndef BASE_CALLBACK_INTERNAL_H_ |
9 | | #define BASE_CALLBACK_INTERNAL_H_ |
10 | | |
11 | | #include "base/base_export.h" |
12 | | #include "base/callback_forward.h" |
13 | | #include "base/macros.h" |
14 | | #include "base/memory/ref_counted.h" |
15 | | |
16 | | namespace base { |
17 | | |
18 | | struct FakeBindState; |
19 | | |
20 | | namespace internal { |
21 | | |
22 | | class CallbackBase; |
23 | | class CallbackBaseCopyable; |
24 | | |
25 | | class BindStateBase; |
26 | | |
27 | | template <typename Functor, typename... BoundArgs> |
28 | | struct BindState; |
29 | | |
30 | | struct BindStateBaseRefCountTraits { |
31 | | static void Destruct(const BindStateBase*); |
32 | | }; |
33 | | |
34 | | // BindStateBase is used to provide an opaque handle that the Callback |
35 | | // class can use to represent a function object with bound arguments. It |
36 | | // behaves as an existential type that is used by a corresponding |
37 | | // DoInvoke function to perform the function execution. This allows |
38 | | // us to shield the Callback class from the types of the bound argument via |
39 | | // "type erasure." |
40 | | // At the base level, the only task is to add reference counting data. Don't use |
41 | | // RefCountedThreadSafe since it requires the destructor to be a virtual method. |
42 | | // Creating a vtable for every BindState template instantiation results in a lot |
43 | | // of bloat. Its only task is to call the destructor which can be done with a |
44 | | // function pointer. |
45 | | class BASE_EXPORT BindStateBase |
46 | | : public RefCountedThreadSafe<BindStateBase, BindStateBaseRefCountTraits> { |
47 | | public: |
48 | | REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE(); |
49 | | |
50 | | using InvokeFuncStorage = void(*)(); |
51 | | |
52 | | private: |
53 | | BindStateBase(InvokeFuncStorage polymorphic_invoke, |
54 | | void (*destructor)(const BindStateBase*)); |
55 | | BindStateBase(InvokeFuncStorage polymorphic_invoke, |
56 | | void (*destructor)(const BindStateBase*), |
57 | | bool (*is_cancelled)(const BindStateBase*)); |
58 | | |
59 | | ~BindStateBase() = default; |
60 | | |
61 | | friend struct BindStateBaseRefCountTraits; |
62 | | friend class RefCountedThreadSafe<BindStateBase, BindStateBaseRefCountTraits>; |
63 | | |
64 | | friend class CallbackBase; |
65 | | friend class CallbackBaseCopyable; |
66 | | |
67 | | // Whitelist subclasses that access the destructor of BindStateBase. |
68 | | template <typename Functor, typename... BoundArgs> |
69 | | friend struct BindState; |
70 | | friend struct ::base::FakeBindState; |
71 | | |
72 | 0 | bool IsCancelled() const { |
73 | 0 | return is_cancelled_(this); |
74 | 0 | } |
75 | | |
76 | | // In C++, it is safe to cast function pointers to function pointers of |
77 | | // another type. It is not okay to use void*. We create a InvokeFuncStorage |
78 | | // that that can store our function pointer, and then cast it back to |
79 | | // the original type on usage. |
80 | | InvokeFuncStorage polymorphic_invoke_; |
81 | | |
82 | | // Pointer to a function that will properly destroy |this|. |
83 | | void (*destructor_)(const BindStateBase*); |
84 | | bool (*is_cancelled_)(const BindStateBase*); |
85 | | |
86 | | DISALLOW_COPY_AND_ASSIGN(BindStateBase); |
87 | | }; |
88 | | |
89 | | // Holds the Callback methods that don't require specialization to reduce |
90 | | // template bloat. |
91 | | // CallbackBase<MoveOnly> is a direct base class of MoveOnly callbacks, and |
92 | | // CallbackBase<Copyable> uses CallbackBase<MoveOnly> for its implementation. |
93 | | class BASE_EXPORT CallbackBase { |
94 | | public: |
95 | | CallbackBase(CallbackBase&& c); |
96 | | CallbackBase& operator=(CallbackBase&& c); |
97 | | |
98 | | explicit CallbackBase(const CallbackBaseCopyable& c); |
99 | | CallbackBase& operator=(const CallbackBaseCopyable& c); |
100 | | |
101 | | explicit CallbackBase(CallbackBaseCopyable&& c); |
102 | | CallbackBase& operator=(CallbackBaseCopyable&& c); |
103 | | |
104 | | // Returns true if Callback is null (doesn't refer to anything). |
105 | 0 | bool is_null() const { return !bind_state_; } |
106 | 0 | explicit operator bool() const { return !is_null(); } |
107 | | |
108 | | // Returns true if the callback invocation will be nop due to an cancellation. |
109 | | // It's invalid to call this on uninitialized callback. |
110 | | bool IsCancelled() const; |
111 | | |
112 | | // Returns the Callback into an uninitialized state. |
113 | | void Reset(); |
114 | | |
115 | | protected: |
116 | | using InvokeFuncStorage = BindStateBase::InvokeFuncStorage; |
117 | | |
118 | | // Returns true if this callback equals |other|. |other| may be null. |
119 | | bool EqualsInternal(const CallbackBase& other) const; |
120 | | |
121 | | // Allow initializing of |bind_state_| via the constructor to avoid default |
122 | | // initialization of the scoped_refptr. |
123 | | explicit CallbackBase(BindStateBase* bind_state); |
124 | | |
125 | 0 | InvokeFuncStorage polymorphic_invoke() const { |
126 | 0 | return bind_state_->polymorphic_invoke_; |
127 | 0 | } |
128 | | |
129 | | // Force the destructor to be instantiated inside this translation unit so |
130 | | // that our subclasses will not get inlined versions. Avoids more template |
131 | | // bloat. |
132 | | ~CallbackBase(); |
133 | | |
134 | | scoped_refptr<BindStateBase> bind_state_; |
135 | | }; |
136 | | |
137 | | // CallbackBase<Copyable> is a direct base class of Copyable Callbacks. |
138 | | class BASE_EXPORT CallbackBaseCopyable : public CallbackBase { |
139 | | public: |
140 | | CallbackBaseCopyable(const CallbackBaseCopyable& c); |
141 | | CallbackBaseCopyable(CallbackBaseCopyable&& c); |
142 | | CallbackBaseCopyable& operator=(const CallbackBaseCopyable& c); |
143 | | CallbackBaseCopyable& operator=(CallbackBaseCopyable&& c); |
144 | | |
145 | | protected: |
146 | | explicit CallbackBaseCopyable(BindStateBase* bind_state) |
147 | 0 | : CallbackBase(bind_state) {} |
148 | 0 | ~CallbackBaseCopyable() {} |
149 | | }; |
150 | | |
151 | | } // namespace internal |
152 | | } // namespace base |
153 | | |
154 | | #endif // BASE_CALLBACK_INTERNAL_H_ |