Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(597)

Side by Side Diff: base/callback_internal.h

Issue 2340153004: Make BindStateBase RefCountedThreadSafe (Closed)
Patch Set: +comment Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | base/callback_internal.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file contains utility functions and classes that help the 5 // This file contains utility functions and classes that help the
6 // implementation, and management of the Callback objects. 6 // implementation, and management of the Callback objects.
7 7
8 #ifndef BASE_CALLBACK_INTERNAL_H_ 8 #ifndef BASE_CALLBACK_INTERNAL_H_
9 #define BASE_CALLBACK_INTERNAL_H_ 9 #define BASE_CALLBACK_INTERNAL_H_
10 10
11 #include "base/atomic_ref_count.h" 11 #include "base/atomic_ref_count.h"
12 #include "base/base_export.h" 12 #include "base/base_export.h"
13 #include "base/callback_forward.h" 13 #include "base/callback_forward.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/memory/ref_counted.h" 15 #include "base/memory/ref_counted.h"
16 16
17 namespace base { 17 namespace base {
18
19 struct FakeBindState1;
20 struct FakeBindState2;
21
18 namespace internal { 22 namespace internal {
19 template <CopyMode copy_mode> 23 template <CopyMode copy_mode>
20 class CallbackBase; 24 class CallbackBase;
21 25
26 template <typename Functor, typename... Args>
27 struct BindState;
28
29 class BindStateBase;
30
22 // BindStateBase is used to provide an opaque handle that the Callback 31 // BindStateBase is used to provide an opaque handle that the Callback
23 // class can use to represent a function object with bound arguments. It 32 // class can use to represent a function object with bound arguments. It
24 // behaves as an existential type that is used by a corresponding 33 // behaves as an existential type that is used by a corresponding
25 // DoInvoke function to perform the function execution. This allows 34 // DoInvoke function to perform the function execution. This allows
26 // us to shield the Callback class from the types of the bound argument via 35 // us to shield the Callback class from the types of the bound argument via
27 // "type erasure." 36 // "type erasure."
28 // At the base level, the only task is to add reference counting data. Don't use 37 // At the base level, the only task is to add reference counting data. Don't use
29 // RefCountedThreadSafe since it requires the destructor to be a virtual method. 38 // RefCountedThreadSafe since it requires the destructor to be a virtual method.
30 // Creating a vtable for every BindState template instantiation results in a lot 39 // Creating a vtable for every BindState template instantiation results in a lot
31 // of bloat. Its only task is to call the destructor which can be done with a 40 // of bloat. Its only task is to call the destructor which can be done with a
32 // function pointer. 41 // function pointer.
33 class BASE_EXPORT BindStateBase { 42
43 struct BASE_EXPORT BindStateBaseRefCountTraits {
44 static void Destruct(const BindStateBase* obj);
dcheng 2016/09/21 22:07:50 Does it make sense to inline the definition in the
45 };
46
47 class BASE_EXPORT BindStateBase
48 : public RefCountedThreadSafe<BindStateBase, BindStateBaseRefCountTraits> {
34 public: 49 public:
35 using InvokeFuncStorage = void(*)(); 50 using InvokeFuncStorage = void(*)();
36 51
37 protected: 52 protected:
38 BindStateBase(InvokeFuncStorage polymorphic_invoke, 53 BindStateBase(InvokeFuncStorage polymorphic_invoke,
39 void (*destructor)(const BindStateBase*)); 54 void (*destructor)(const BindStateBase*));
40 BindStateBase(InvokeFuncStorage polymorphic_invoke, 55 BindStateBase(InvokeFuncStorage polymorphic_invoke,
41 void (*destructor)(const BindStateBase*), 56 void (*destructor)(const BindStateBase*),
42 bool (*is_cancelled)(const BindStateBase*)); 57 bool (*is_cancelled)(const BindStateBase*));
43 ~BindStateBase() = default;
44 58
45 private: 59 private:
46 friend class scoped_refptr<BindStateBase>; 60 friend class scoped_refptr<BindStateBase>;
47 template <CopyMode copy_mode> 61 template <CopyMode copy_mode>
48 friend class CallbackBase; 62 friend class CallbackBase;
49 63
64 // Add known callers of the destructor as friend classes. Note that making the
65 // destructor protected hits a chromium style check done by the clang plugin.
66 friend struct BindStateBaseRefCountTraits;
67 template <typename Functor, typename... BoundArgs>
68 friend struct BindState;
dcheng 2016/09/21 22:07:50 It feels a bit funny that we have to friend both t
69 friend struct base::FakeBindState1;
70 friend struct base::FakeBindState2;
dcheng 2016/09/21 22:07:50 I'm a bit sad about having to friend these test on
71
72 ~BindStateBase() = default;
73
50 bool IsCancelled() const { 74 bool IsCancelled() const {
51 return is_cancelled_(this); 75 return is_cancelled_(this);
52 } 76 }
53 77
54 void AddRef() const;
55 void Release() const;
56
57 // In C++, it is safe to cast function pointers to function pointers of 78 // In C++, it is safe to cast function pointers to function pointers of
58 // another type. It is not okay to use void*. We create a InvokeFuncStorage 79 // another type. It is not okay to use void*. We create a InvokeFuncStorage
59 // that that can store our function pointer, and then cast it back to 80 // that that can store our function pointer, and then cast it back to
60 // the original type on usage. 81 // the original type on usage.
61 InvokeFuncStorage polymorphic_invoke_; 82 InvokeFuncStorage polymorphic_invoke_;
62 83
63 mutable AtomicRefCount ref_count_;
64
65 // Pointer to a function that will properly destroy |this|. 84 // Pointer to a function that will properly destroy |this|.
66 void (*destructor_)(const BindStateBase*); 85 void (*destructor_)(const BindStateBase*);
67 bool (*is_cancelled_)(const BindStateBase*); 86 bool (*is_cancelled_)(const BindStateBase*);
68 87
69 DISALLOW_COPY_AND_ASSIGN(BindStateBase); 88 DISALLOW_COPY_AND_ASSIGN(BindStateBase);
70 }; 89 };
71 90
72 // Holds the Callback methods that don't require specialization to reduce 91 // Holds the Callback methods that don't require specialization to reduce
73 // template bloat. 92 // template bloat.
74 // CallbackBase<MoveOnly> is a direct base class of MoveOnly callbacks, and 93 // CallbackBase<MoveOnly> is a direct base class of MoveOnly callbacks, and
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 ~CallbackBase() {} 149 ~CallbackBase() {}
131 }; 150 };
132 151
133 extern template class CallbackBase<CopyMode::MoveOnly>; 152 extern template class CallbackBase<CopyMode::MoveOnly>;
134 extern template class CallbackBase<CopyMode::Copyable>; 153 extern template class CallbackBase<CopyMode::Copyable>;
135 154
136 } // namespace internal 155 } // namespace internal
137 } // namespace base 156 } // namespace base
138 157
139 #endif // BASE_CALLBACK_INTERNAL_H_ 158 #endif // BASE_CALLBACK_INTERNAL_H_
OLDNEW
« no previous file with comments | « no previous file | base/callback_internal.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698