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

Side by Side Diff: base/callback_internal.h

Issue 2317563002: Move CallbackBase::polymorphic_invoke_ into BindStateBase (Closed)
Patch Set: rebase 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 | « base/callback.h ('k') | 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
(...skipping 13 matching lines...) Expand all
24 // behaves as an existential type that is used by a corresponding 24 // behaves as an existential type that is used by a corresponding
25 // DoInvoke function to perform the function execution. This allows 25 // DoInvoke function to perform the function execution. This allows
26 // us to shield the Callback class from the types of the bound argument via 26 // us to shield the Callback class from the types of the bound argument via
27 // "type erasure." 27 // "type erasure."
28 // At the base level, the only task is to add reference counting data. Don't use 28 // 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. 29 // RefCountedThreadSafe since it requires the destructor to be a virtual method.
30 // Creating a vtable for every BindState template instantiation results in a lot 30 // 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 31 // of bloat. Its only task is to call the destructor which can be done with a
32 // function pointer. 32 // function pointer.
33 class BindStateBase { 33 class BindStateBase {
34 public:
35 using InvokeFuncStorage = void(*)();
36
34 protected: 37 protected:
35 explicit BindStateBase(void (*destructor)(BindStateBase*)) 38 BindStateBase(InvokeFuncStorage polymorphic_invoke,
36 : ref_count_(0), destructor_(destructor) {} 39 void (*destructor)(BindStateBase*))
40 : polymorphic_invoke_(polymorphic_invoke),
41 ref_count_(0), destructor_(destructor) {}
37 ~BindStateBase() = default; 42 ~BindStateBase() = default;
38 43
39 private: 44 private:
40 friend class scoped_refptr<BindStateBase>; 45 friend class scoped_refptr<BindStateBase>;
41 template <CopyMode copy_mode> 46 template <CopyMode copy_mode>
42 friend class CallbackBase; 47 friend class CallbackBase;
43 48
44 void AddRef(); 49 void AddRef();
45 void Release(); 50 void Release();
46 51
52 // In C++, it is safe to cast function pointers to function pointers of
53 // another type. It is not okay to use void*. We create a InvokeFuncStorage
54 // that that can store our function pointer, and then cast it back to
55 // the original type on usage.
56 InvokeFuncStorage polymorphic_invoke_;
57
47 AtomicRefCount ref_count_; 58 AtomicRefCount ref_count_;
48 59
49 // Pointer to a function that will properly destroy |this|. 60 // Pointer to a function that will properly destroy |this|.
50 void (*destructor_)(BindStateBase*); 61 void (*destructor_)(BindStateBase*);
51 62
52 DISALLOW_COPY_AND_ASSIGN(BindStateBase); 63 DISALLOW_COPY_AND_ASSIGN(BindStateBase);
53 }; 64 };
54 65
55 // Holds the Callback methods that don't require specialization to reduce 66 // Holds the Callback methods that don't require specialization to reduce
56 // template bloat. 67 // template bloat.
57 // CallbackBase<MoveOnly> is a direct base class of MoveOnly callbacks, and 68 // CallbackBase<MoveOnly> is a direct base class of MoveOnly callbacks, and
58 // CallbackBase<Copyable> uses CallbackBase<MoveOnly> for its implementation. 69 // CallbackBase<Copyable> uses CallbackBase<MoveOnly> for its implementation.
59 template <> 70 template <>
60 class BASE_EXPORT CallbackBase<CopyMode::MoveOnly> { 71 class BASE_EXPORT CallbackBase<CopyMode::MoveOnly> {
61 public: 72 public:
62 CallbackBase(CallbackBase&& c); 73 CallbackBase(CallbackBase&& c);
63 CallbackBase& operator=(CallbackBase&& c); 74 CallbackBase& operator=(CallbackBase&& c);
64 75
65 // Returns true if Callback is null (doesn't refer to anything). 76 // Returns true if Callback is null (doesn't refer to anything).
66 bool is_null() const { return bind_state_.get() == NULL; } 77 bool is_null() const { return bind_state_.get() == NULL; }
67 explicit operator bool() const { return !is_null(); } 78 explicit operator bool() const { return !is_null(); }
68 79
69 // Returns the Callback into an uninitialized state. 80 // Returns the Callback into an uninitialized state.
70 void Reset(); 81 void Reset();
71 82
72 protected: 83 protected:
73 // In C++, it is safe to cast function pointers to function pointers of 84 using InvokeFuncStorage = BindStateBase::InvokeFuncStorage;
74 // another type. It is not okay to use void*. We create a InvokeFuncStorage
75 // that that can store our function pointer, and then cast it back to
76 // the original type on usage.
77 using InvokeFuncStorage = void(*)();
78 85
79 // Returns true if this callback equals |other|. |other| may be null. 86 // Returns true if this callback equals |other|. |other| may be null.
80 bool EqualsInternal(const CallbackBase& other) const; 87 bool EqualsInternal(const CallbackBase& other) const;
81 88
82 // Allow initializing of |bind_state_| via the constructor to avoid default 89 // Allow initializing of |bind_state_| via the constructor to avoid default
83 // initialization of the scoped_refptr. We do not also initialize 90 // initialization of the scoped_refptr.
84 // |polymorphic_invoke_| here because doing a normal assignment in the
85 // derived Callback templates makes for much nicer compiler errors.
86 explicit CallbackBase(BindStateBase* bind_state); 91 explicit CallbackBase(BindStateBase* bind_state);
87 92
93 InvokeFuncStorage polymorphic_invoke() const {
94 return bind_state_->polymorphic_invoke_;
95 }
96
88 // Force the destructor to be instantiated inside this translation unit so 97 // Force the destructor to be instantiated inside this translation unit so
89 // that our subclasses will not get inlined versions. Avoids more template 98 // that our subclasses will not get inlined versions. Avoids more template
90 // bloat. 99 // bloat.
91 ~CallbackBase(); 100 ~CallbackBase();
92 101
93 scoped_refptr<BindStateBase> bind_state_; 102 scoped_refptr<BindStateBase> bind_state_;
94 InvokeFuncStorage polymorphic_invoke_ = nullptr;
95 }; 103 };
96 104
97 // CallbackBase<Copyable> is a direct base class of Copyable Callbacks. 105 // CallbackBase<Copyable> is a direct base class of Copyable Callbacks.
98 template <> 106 template <>
99 class BASE_EXPORT CallbackBase<CopyMode::Copyable> 107 class BASE_EXPORT CallbackBase<CopyMode::Copyable>
100 : public CallbackBase<CopyMode::MoveOnly> { 108 : public CallbackBase<CopyMode::MoveOnly> {
101 public: 109 public:
102 CallbackBase(const CallbackBase& c); 110 CallbackBase(const CallbackBase& c);
103 CallbackBase(CallbackBase&& c); 111 CallbackBase(CallbackBase&& c);
104 CallbackBase& operator=(const CallbackBase& c); 112 CallbackBase& operator=(const CallbackBase& c);
105 CallbackBase& operator=(CallbackBase&& c); 113 CallbackBase& operator=(CallbackBase&& c);
106 protected: 114 protected:
107 explicit CallbackBase(BindStateBase* bind_state) 115 explicit CallbackBase(BindStateBase* bind_state)
108 : CallbackBase<CopyMode::MoveOnly>(bind_state) {} 116 : CallbackBase<CopyMode::MoveOnly>(bind_state) {}
109 ~CallbackBase() {} 117 ~CallbackBase() {}
110 }; 118 };
111 119
112 extern template class CallbackBase<CopyMode::MoveOnly>; 120 extern template class CallbackBase<CopyMode::MoveOnly>;
113 extern template class CallbackBase<CopyMode::Copyable>; 121 extern template class CallbackBase<CopyMode::Copyable>;
114 122
115 } // namespace internal 123 } // namespace internal
116 } // namespace base 124 } // namespace base
117 125
118 #endif // BASE_CALLBACK_INTERNAL_H_ 126 #endif // BASE_CALLBACK_INTERNAL_H_
OLDNEW
« no previous file with comments | « base/callback.h ('k') | base/callback_internal.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698