callback_internal.h 6.5 KB

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