Skip to content

Commit

Permalink
Revert of "Redo r113722 - Add Pass(), which implements move semantics…
Browse files Browse the repository at this point in the history
…, to scoped_ptr, scoped_ar..."

This reverts commit r113922.

Win Canary has been failing to link due to OOM since the weekend.  While this was not the original cause, it might be making things worse.  Speculatively remove for now.

Also changes render_widge_host_view to use Owned() instead of Passed().

BUG=none
TEST=existing.

Review URL: http://codereview.chromium.org/8931008

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114247 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
ajwong@chromium.org committed Dec 13, 2011
1 parent ab9fe0f commit 54af837
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 657 deletions.
152 changes: 31 additions & 121 deletions base/bind_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,19 @@
// can be used specify the refcounting and reference semantics of arguments
// that are bound by the Bind() function in base/bind.h.
//
// The public functions are base::Unretained(), base::Owned(), bass::Passed(),
// base::ConstRef(), and base::IgnoreResult().
// The public functions are base::Unretained(), base::Owned(),
// base::ConstRef(), and base::IgnoreReturn().
//
// Unretained() allows Bind() to bind a non-refcounted class, and to disable
// refcounting on arguments that are refcounted objects.
//
// Owned() transfers ownership of an object to the Callback resulting from
// bind; the object will be deleted when the Callback is deleted.
//
// Passed() is for transferring movable-but-not-copyable types (eg. scoped_ptr)
// through a Callback. Logically, this signifies a destructive transfer of
// the state of the argument into the target function. Invoking
// Callback::Run() twice on a Callback that was created with a Passed()
// argument will CHECK() because the first invocation would have already
// transferred ownership to the target function.
//
// ConstRef() allows binding a constant reference to an argument rather
// than a copy.
// IgnoreReturn() is used to adapt a 0-argument Callback with a return type to
// a Closure. This is useful if you need to PostTask with a function that has
// a return value that you don't care about.
//
// IgnoreResult() is used to adapt a function or Callback with a return type to
// one with a void return. This is most useful if you have a function with,
// say, a pesky ignorable bool return that you want to use with PostTask or
// something else that expect a Callback with a void return.
//
// EXAMPLE OF Unretained():
//
Expand Down Expand Up @@ -85,45 +75,13 @@
// its bound callbacks.
//
//
// EXAMPLE OF IgnoreResult():
// EXAMPLE OF IgnoreReturn():
//
// int DoSomething(int arg) { cout << arg << endl; }
//
// // Assign to a Callback with a void return type.
// Callback<void(int)> cb = Bind(IgnoreResult(&DoSomething));
// cb->Run(1); // Prints "1".
//
// // Prints "1" on |ml|.
// ml->PostTask(FROM_HERE, Bind(IgnoreResult(&DoSomething), 1);
//
//
// EXAMPLE OF Passed():
//
// void TakesOwnership(scoped_ptr<Foo> arg) { }
// scoped_ptr<Foo> CreateFoo() { return scoped_ptr<Foo>(new Foo()); }
//
// scoped_ptr<Foo> f(new Foo());
//
// // |cb| is given ownership of Foo(). |f| is now NULL.
// // You can use f.Pass() in place of &f, but it's more verbose.
// Closure cb = Bind(&TakesOwnership, Passed(&f));
//
// // Run was never called so |cb| still owns Foo() and deletes
// // it on Reset().
// cb.Reset();
//
// // |cb| is given a new Foo created by CreateFoo().
// cb = Bind(&TakesOwnership, Passed(CreateFoo()));
//
// // |arg| in TakesOwnership() is given ownership of Foo(). |cb|
// // no longer owns Foo() and, if reset, would not delete Foo().
// cb.Run(); // Foo() is now transferred to |arg| and deleted.
// cb.Run(); // This CHECK()s since Foo() already been used once.
//
// Passed() is particularly useful with PostTask() when you are transferring
// ownership of an argument into a task, but don't necessarily know if the
// task will always be executed. This can happen if the task is cancellable
// or if it is posted to a MessageLoopProxy.
// Callback<int(void)> cb = Bind(&DoSomething, 1);
// Closure c = IgnoreReturn(cb); // Prints "1"
// or
// ml->PostTask(FROM_HERE, IgnoreReturn(cb)); // Prints "1" on |ml|

#ifndef BASE_BIND_HELPERS_H_
#define BASE_BIND_HELPERS_H_
Expand Down Expand Up @@ -329,45 +287,6 @@ class OwnedWrapper {
mutable T* ptr_;
};

// PassedWrapper is a copyable adapter for a scoper that ignores const.
//
// It is needed to get around the fact that Bind() takes a const reference to
// all its arguments. Because Bind() takes a const reference to avoid
// unnecessary copies, it is incompatible with movable-but-not-copyable
// types; doing a destructive "move" of the type into Bind() would violate
// the const correctness.
//
// This conundrum cannot be solved without either C++11 rvalue references or
// a O(2^n) blowup of Bind() templates to handle each combination of regular
// types and movable-but-not-copyable types. Thus we introduce a wrapper type
// that is copyable to transmit the correct type information down into
// BindState<>. Ignoring const in this type makes sense because it is only
// created when we are explicitly trying to do a destructive move.
//
// Two notes:
// 1) PassedWrapper supports any type that has a "Pass()" function.
// This is intentional. The whitelisting of which specific types we
// support is maintained by CallbackParamTraits<>.
// 2) is_valid_ is distinct from NULL because it is valid to bind a "NULL"
// scoper to a Callback and allow the Callback to execute once.
template <typename T>
class PassedWrapper {
public:
explicit PassedWrapper(T scoper) : is_valid_(true), scoper_(scoper.Pass()) {}
PassedWrapper(const PassedWrapper& other)
: is_valid_(other.is_valid_), scoper_(other.scoper_.Pass()) {
}
T Pass() const {
CHECK(is_valid_);
is_valid_ = false;
return scoper_.Pass();
}

private:
mutable bool is_valid_;
mutable T scoper_;
};

// Unwrap the stored parameters for the wrappers above.
template <typename T>
struct UnwrapTraits {
Expand Down Expand Up @@ -411,17 +330,9 @@ struct UnwrapTraits<OwnedWrapper<T> > {
}
};

template <typename T>
struct UnwrapTraits<PassedWrapper<T> > {
typedef T ForwardType;
static T Unwrap(PassedWrapper<T>& o) {
return o.Pass();
}
};

// Utility for handling different refcounting semantics in the Bind()
// function.
template <bool is_method, typename T>
template <bool, typename T>
struct MaybeRefcount;

template <typename T>
Expand All @@ -436,18 +347,24 @@ struct MaybeRefcount<false, T[n]> {
static void Release(const T*) {}
};

template <typename T>
struct MaybeRefcount<true, T> {
static void AddRef(const T&) {}
static void Release(const T&) {}
};

template <typename T>
struct MaybeRefcount<true, T*> {
static void AddRef(T* o) { o->AddRef(); }
static void Release(T* o) { o->Release(); }
};

template <typename T>
struct MaybeRefcount<true, UnretainedWrapper<T> > {
static void AddRef(const UnretainedWrapper<T>&) {}
static void Release(const UnretainedWrapper<T>&) {}
};

template <typename T>
struct MaybeRefcount<true, OwnedWrapper<T> > {
static void AddRef(const OwnedWrapper<T>&) {}
static void Release(const OwnedWrapper<T>&) {}
};

// No need to additionally AddRef() and Release() since we are storing a
// scoped_refptr<> inside the storage object already.
template <typename T>
Expand All @@ -462,13 +379,19 @@ struct MaybeRefcount<true, const T*> {
static void Release(const T* o) { o->Release(); }
};

template <typename T>
struct MaybeRefcount<true, WeakPtr<T> > {
static void AddRef(const WeakPtr<T>&) {}
static void Release(const WeakPtr<T>&) {}
};

template <typename R>
void VoidReturnAdapter(Callback<R(void)> callback) {
callback.Run();
}

// IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a
// method. It is used internally by Bind() to select the correct
// method. It is unsed internally by Bind() to select the correct
// InvokeHelper that will no-op itself in the event the WeakPtr<> for
// the target object is invalidated.
//
Expand Down Expand Up @@ -499,20 +422,6 @@ static inline internal::OwnedWrapper<T> Owned(T* o) {
return internal::OwnedWrapper<T>(o);
}

// We offer 2 syntaxes for calling Passed(). The first takes a temporary and
// is best suited for use with the return value of a function. The second
// takes a pointer to the scoper and is just syntactic sugar to avoid having
// to write Passed(scoper.Pass()).
template <typename T>
static inline internal::PassedWrapper<T> Passed(T scoper) {
return internal::PassedWrapper<T>(scoper.Pass());
}
template <typename T>
static inline internal::PassedWrapper<T> Passed(T* scoper) {
return internal::PassedWrapper<T>(scoper->Pass());
}

// -- DEPRECATED -- Use IgnoreResult instead.
template <typename R>
static inline Closure IgnoreReturn(Callback<R(void)> callback) {
return Bind(&internal::VoidReturnAdapter<R>, callback);
Expand All @@ -529,6 +438,7 @@ IgnoreResult(const Callback<T>& data) {
return internal::IgnoreResultHelper<Callback<T> >(data);
}


} // namespace base

#endif // BASE_BIND_HELPERS_H_
Loading

0 comments on commit 54af837

Please sign in to comment.