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