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