1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Use of this source code is governed by a BSD-style license that can be 3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// found in the LICENSE file. 4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// This file contains utility functions and classes that help the 6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// implementation, and management of the Callback objects. 7b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 8b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#ifndef BASE_CALLBACK_INTERNAL_H_ 9b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#define BASE_CALLBACK_INTERNAL_H_ 10b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 11b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/base_export.h" 1245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko#include "base/callback_forward.h" 13b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/macros.h" 14b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/memory/ref_counted.h" 15b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace base { 17f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe 18f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abestruct FakeBindState; 19f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe 20b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace internal { 21f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe 2245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkotemplate <CopyMode copy_mode> 23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass CallbackBase; 24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 25f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abeclass BindStateBase; 26f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe 27f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abetemplate <typename Functor, typename... BoundArgs> 28f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abestruct BindState; 29f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe 30f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abestruct BindStateBaseRefCountTraits { 31f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe static void Destruct(const BindStateBase*); 32f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe}; 33f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe 34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// BindStateBase is used to provide an opaque handle that the Callback 35b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// class can use to represent a function object with bound arguments. It 36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// behaves as an existential type that is used by a corresponding 37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// DoInvoke function to perform the function execution. This allows 38b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// us to shield the Callback class from the types of the bound argument via 39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// "type erasure." 40b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// At the base level, the only task is to add reference counting data. Don't use 41b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// RefCountedThreadSafe since it requires the destructor to be a virtual method. 42b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Creating a vtable for every BindState template instantiation results in a lot 43b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// of bloat. Its only task is to call the destructor which can be done with a 44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// function pointer. 45f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abeclass BASE_EXPORT BindStateBase 46f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe : public RefCountedThreadSafe<BindStateBase, BindStateBaseRefCountTraits> { 4736040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe public: 48f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE(); 49f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe 5036040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe using InvokeFuncStorage = void(*)(); 5136040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe 52f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe private: 5336040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe BindStateBase(InvokeFuncStorage polymorphic_invoke, 5436040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe void (*destructor)(const BindStateBase*)); 5536040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe BindStateBase(InvokeFuncStorage polymorphic_invoke, 5636040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe void (*destructor)(const BindStateBase*), 5736040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe bool (*is_cancelled)(const BindStateBase*)); 58f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe 59b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ~BindStateBase() = default; 60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 61f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe friend struct BindStateBaseRefCountTraits; 62f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe friend class RefCountedThreadSafe<BindStateBase, BindStateBaseRefCountTraits>; 63f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe 6445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko template <CopyMode copy_mode> 65b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat friend class CallbackBase; 66b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 67f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe // Whitelist subclasses that access the destructor of BindStateBase. 68f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe template <typename Functor, typename... BoundArgs> 69f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe friend struct BindState; 70f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe friend struct ::base::FakeBindState; 71f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe 7236040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe bool IsCancelled() const { 7336040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe return is_cancelled_(this); 7436040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe } 7536040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe 7636040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe // In C++, it is safe to cast function pointers to function pointers of 7736040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe // another type. It is not okay to use void*. We create a InvokeFuncStorage 7836040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe // that that can store our function pointer, and then cast it back to 7936040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe // the original type on usage. 8036040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe InvokeFuncStorage polymorphic_invoke_; 81b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Pointer to a function that will properly destroy |this|. 8336040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe void (*destructor_)(const BindStateBase*); 8436040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe bool (*is_cancelled_)(const BindStateBase*); 85b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DISALLOW_COPY_AND_ASSIGN(BindStateBase); 87b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}; 88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Holds the Callback methods that don't require specialization to reduce 90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// template bloat. 9145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko// CallbackBase<MoveOnly> is a direct base class of MoveOnly callbacks, and 9245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko// CallbackBase<Copyable> uses CallbackBase<MoveOnly> for its implementation. 9345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkotemplate <> 9445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkoclass BASE_EXPORT CallbackBase<CopyMode::MoveOnly> { 95b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat public: 9645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko CallbackBase(CallbackBase&& c); 9745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko CallbackBase& operator=(CallbackBase&& c); 98b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 9936040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe explicit CallbackBase(const CallbackBase<CopyMode::Copyable>& c); 10036040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe CallbackBase& operator=(const CallbackBase<CopyMode::Copyable>& c); 10136040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe 10236040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe explicit CallbackBase(CallbackBase<CopyMode::Copyable>&& c); 10336040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe CallbackBase& operator=(CallbackBase<CopyMode::Copyable>&& c); 10436040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe 105b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Returns true if Callback is null (doesn't refer to anything). 106f810b5921dde57180956b9eadf39a3a2b8cb5855Hidehiko Abe bool is_null() const { return !bind_state_; } 1070c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez explicit operator bool() const { return !is_null(); } 108b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 10936040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe // Returns true if the callback invocation will be nop due to an cancellation. 11036040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe // It's invalid to call this on uninitialized callback. 11136040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe bool IsCancelled() const; 11236040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe 113b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Returns the Callback into an uninitialized state. 114b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void Reset(); 115b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 116b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat protected: 11736040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe using InvokeFuncStorage = BindStateBase::InvokeFuncStorage; 118b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 119b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Returns true if this callback equals |other|. |other| may be null. 12045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko bool EqualsInternal(const CallbackBase& other) const; 121b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 122b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Allow initializing of |bind_state_| via the constructor to avoid default 12336040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe // initialization of the scoped_refptr. 124b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat explicit CallbackBase(BindStateBase* bind_state); 125b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 12636040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe InvokeFuncStorage polymorphic_invoke() const { 12736040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe return bind_state_->polymorphic_invoke_; 12836040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe } 12936040ed30c39d2106a2cd5ec033e98b71302a744Hidehiko Abe 130b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Force the destructor to be instantiated inside this translation unit so 131b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // that our subclasses will not get inlined versions. Avoids more template 132b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // bloat. 133b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ~CallbackBase(); 134b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 135b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat scoped_refptr<BindStateBase> bind_state_; 13645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko}; 13745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 13845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko// CallbackBase<Copyable> is a direct base class of Copyable Callbacks. 13945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkotemplate <> 14045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkoclass BASE_EXPORT CallbackBase<CopyMode::Copyable> 14145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko : public CallbackBase<CopyMode::MoveOnly> { 14245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko public: 14345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko CallbackBase(const CallbackBase& c); 14445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko CallbackBase(CallbackBase&& c); 14545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko CallbackBase& operator=(const CallbackBase& c); 14645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko CallbackBase& operator=(CallbackBase&& c); 14745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko protected: 14845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko explicit CallbackBase(BindStateBase* bind_state) 14945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko : CallbackBase<CopyMode::MoveOnly>(bind_state) {} 15045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko ~CallbackBase() {} 151b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}; 152b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 15345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkoextern template class CallbackBase<CopyMode::MoveOnly>; 15445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkoextern template class CallbackBase<CopyMode::Copyable>; 15545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 156b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace internal 157b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace base 158b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 159b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif // BASE_CALLBACK_INTERNAL_H_ 160