summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorvmpstr <vmpstr@chromium.org>2016-03-18 13:46:41 -0700
committerCommit bot <commit-bot@chromium.org>2016-03-18 20:48:37 +0000
commit1d492be0508e1638a37ac6a156d16e9f724da69c (patch)
tree09b8f1f2937a3c59ed60ff999ede5f5530318d5e /base
parent4646679d35fcf63a03155e8a454df099a74d2788 (diff)
downloadchromium_src-1d492be0508e1638a37ac6a156d16e9f724da69c.zip
chromium_src-1d492be0508e1638a37ac6a156d16e9f724da69c.tar.gz
chromium_src-1d492be0508e1638a37ac6a156d16e9f724da69c.tar.bz2
base: Add RetainedRef for unwrapping scoped_refptrs.
This patch adds a RetainedRef call in order to be used in Bind with scoped_refptrs that are to be unwrapped before calling the function. This is an effort to eliminate implicit scoped_refptr construction from Bind. Currently, scoped_refptr are always unwrapped into their underlying T*. This means that if the function does actually expect a scoped_refptr, one will be constructed implicitly. The plan is to stop unwrapping scoped_refptrs altogether. If the behavior is still desired, then the object has to be wrapped in a RetainedRef wrapper. For more details, please see crbug.com/589048 R=tzik@chromium.org, danakj@chromium.org, thakis@chromium.org BUG=589048 Review URL: https://codereview.chromium.org/1815493002 Cr-Commit-Position: refs/heads/master@{#382076}
Diffstat (limited to 'base')
-rw-r--r--base/bind_helpers.h41
1 files changed, 41 insertions, 0 deletions
diff --git a/base/bind_helpers.h b/base/bind_helpers.h
index 117fc68..81dba6d 100644
--- a/base/bind_helpers.h
+++ b/base/bind_helpers.h
@@ -28,6 +28,9 @@
// argument will CHECK() because the first invocation would have already
// transferred ownership to the target function.
//
+// RetainedRef() accepts a ref counted object and retains a reference to it.
+// When the callback is called, the object is passed as a raw pointer.
+//
// ConstRef() allows binding a constant reference to an argument rather
// than a copy.
//
@@ -71,6 +74,19 @@
// Without Owned(), someone would have to know to delete |pn| when the last
// reference to the Callback is deleted.
//
+// EXAMPLE OF RetainedRef():
+//
+// void foo(RefCountedBytes* bytes) {}
+//
+// scoped_refptr<RefCountedBytes> bytes = ...;
+// Closure callback = Bind(&foo, base::RetainedRef(bytes));
+// callback.Run();
+//
+// Without RetainedRef, the scoped_refptr would try to implicitly convert to
+// a raw pointer and fail compilation:
+//
+// Closure callback = Bind(&foo, bytes); // ERROR!
+//
//
// EXAMPLE OF ConstRef():
//
@@ -312,6 +328,16 @@ class ConstRefWrapper {
};
template <typename T>
+class RetainedRefWrapper {
+ public:
+ explicit RetainedRefWrapper(T* o) : ptr_(o) {}
+ explicit RetainedRefWrapper(scoped_refptr<T> o) : ptr_(std::move(o)) {}
+ T* get() const { return ptr_.get(); }
+ private:
+ scoped_refptr<T> ptr_;
+};
+
+template <typename T>
struct IgnoreResultHelper {
explicit IgnoreResultHelper(T functor) : functor_(functor) {}
@@ -410,6 +436,11 @@ T* Unwrap(const scoped_refptr<T>& o) {
}
template <typename T>
+T* Unwrap(const RetainedRefWrapper<T>& o) {
+ return o.get();
+}
+
+template <typename T>
const WeakPtr<T>& Unwrap(const WeakPtr<T>& o) {
return o;
}
@@ -545,6 +576,16 @@ static inline internal::UnretainedWrapper<T> Unretained(T* o) {
}
template <typename T>
+static inline internal::RetainedRefWrapper<T> RetainedRef(T* o) {
+ return internal::RetainedRefWrapper<T>(o);
+}
+
+template <typename T>
+static inline internal::RetainedRefWrapper<T> RetainedRef(scoped_refptr<T> o) {
+ return internal::RetainedRefWrapper<T>(std::move(o));
+}
+
+template <typename T>
static inline internal::ConstRefWrapper<T> ConstRef(const T& o) {
return internal::ConstRefWrapper<T>(o);
}