Coverage Report

Created: 2018-09-25 14:53

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