callback_internal.h revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2011 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#pragma once
11
12#include "base/ref_counted.h"
13
14namespace base {
15namespace internal {
16
17// InvokerStorageBase is used to provide an opaque handle that the Callback
18// class can use to represent a function object with bound arguments.  It
19// behaves as an existential type that is used by a corresponding
20// DoInvoke function to perform the function execution.  This allows
21// us to shield the Callback class from the types of the bound argument via
22// "type erasure."
23class InvokerStorageBase : public RefCountedThreadSafe<InvokerStorageBase> {
24 protected:
25  friend class RefCountedThreadSafe<InvokerStorageBase>;
26  virtual ~InvokerStorageBase() {}
27};
28
29// This structure exists purely to pass the returned |invoker_storage_| from
30// Bind() to Callback while avoiding an extra AddRef/Release() pair.
31//
32// To do this, the constructor of Callback<> must take a const-ref.  The
33// reference must be to a const object otherwise the compiler will emit a
34// warning about taking a reference to a temporary.
35//
36// Unfortunately, this means that the internal |invoker_storage_| field must
37// be made mutable.
38template <typename T>
39struct InvokerStorageHolder {
40  explicit InvokerStorageHolder(T* invoker_storage)
41      : invoker_storage_(invoker_storage) {
42  }
43
44  mutable scoped_refptr<InvokerStorageBase> invoker_storage_;
45};
46
47template <typename T>
48InvokerStorageHolder<T> MakeInvokerStorageHolder(T* o) {
49  return InvokerStorageHolder<T>(o);
50}
51
52// Holds the Callback methods that don't require specialization to reduce
53// template bloat.
54class CallbackBase {
55 public:
56  // Returns true if Callback is null (doesn't refer to anything).
57  bool is_null() const;
58
59  // Returns the Callback into an uninitalized state.
60  void Reset();
61
62  bool Equals(const CallbackBase& other) const;
63
64 protected:
65  // In C++, it is safe to cast function pointers to function pointers of
66  // another type. It is not okay to use void*. We create a InvokeFuncStorage
67  // that that can store our function pointer, and then cast it back to
68  // the original type on usage.
69  typedef void(*InvokeFuncStorage)(void);
70
71  CallbackBase(InvokeFuncStorage polymorphic_invoke,
72               scoped_refptr<InvokerStorageBase>* invoker_storage);
73
74  // Force the destructor to be instaniated inside this translation unit so
75  // that our subclasses will not get inlined versions.  Avoids more template
76  // bloat.
77  ~CallbackBase();
78
79  scoped_refptr<InvokerStorageBase> invoker_storage_;
80  InvokeFuncStorage polymorphic_invoke_;
81};
82
83}  // namespace internal
84}  // namespace base
85
86#endif  // BASE_CALLBACK_INTERNAL_H_
87