| Index: base/bind_unittest.cc
|
| diff --git a/base/bind_unittest.cc b/base/bind_unittest.cc
|
| index 654a2775a2f23efc2f266d8db8286e20fed15b0a..7a2808ee1544ccc11740d6f341b115ae5e89108c 100644
|
| --- a/base/bind_unittest.cc
|
| +++ b/base/bind_unittest.cc
|
| @@ -5,6 +5,9 @@
|
| #include "base/bind.h"
|
|
|
| #include "base/callback.h"
|
| +#include "base/memory/pass_scoped_ptr.h"
|
| +#include "base/memory/ref_counted.h"
|
| +#include "base/memory/weak_ptr.h"
|
| #include "testing/gmock/include/gmock/gmock.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| @@ -149,6 +152,18 @@ class DeleteCounter {
|
| int* deletes_;
|
| };
|
|
|
| +DeleteCounter* MaybeCapture(const PassScopedPtr<DeleteCounter>& ptr,
|
| + bool expect_valid,
|
| + bool should_capture) {
|
| + EXPECT_EQ(expect_valid, ptr.is_valid());
|
| + if (should_capture) {
|
| + scoped_ptr<DeleteCounter> scoped;
|
| + ptr.ToScopedPtr(&scoped);
|
| + return scoped.release();
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| // Some test functions that we can Bind to.
|
| template <typename T>
|
| T PolymorphicIdentity(T t) {
|
| @@ -641,8 +656,8 @@ TEST_F(BindTest, Owned) {
|
| // return the same value.
|
| Callback<DeleteCounter*(void)> no_capture_cb =
|
| Bind(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
|
| - EXPECT_EQ(counter, no_capture_cb.Run());
|
| - EXPECT_EQ(counter, no_capture_cb.Run());
|
| + ASSERT_EQ(counter, no_capture_cb.Run());
|
| + ASSERT_EQ(counter, no_capture_cb.Run());
|
| EXPECT_EQ(0, deletes);
|
| no_capture_cb.Reset(); // This should trigger a delete.
|
| EXPECT_EQ(1, deletes);
|
| @@ -657,6 +672,48 @@ TEST_F(BindTest, Owned) {
|
| EXPECT_EQ(1, deletes);
|
| }
|
|
|
| +// PassScopedPtr() wrapper support.
|
| +// - Binding PassScopedPtr gives Callback Ownership.
|
| +// - Callback only transfers ownership of PassScopedPtr on explicit Pass()
|
| +// or ToScopedPtr() call.
|
| +TEST_F(BindTest, PassScopedPtr) {
|
| + int deletes = 0;
|
| +
|
| + // If we never invoke the Callback, it returns ownership and deletes.
|
| + Callback<DeleteCounter*(bool, bool)> unused_callback =
|
| + Bind(&MaybeCapture,
|
| + MakePassScopedPtr(new DeleteCounter(&deletes)).PassForBind());
|
| + EXPECT_EQ(0, deletes);
|
| + unused_callback.Reset();
|
| + EXPECT_EQ(1, deletes);
|
| +
|
| + // Check that ownership is only transfered if ToScopedPtr() is called.
|
| + deletes = 0;
|
| + DeleteCounter* counter = new DeleteCounter(&deletes);
|
| + EXPECT_EQ(0, deletes);
|
| + Callback<DeleteCounter*(bool, bool)> callback =
|
| + Bind(&MaybeCapture, MakePassScopedPtr(counter).PassForBind());
|
| + EXPECT_EQ(0, deletes);
|
| +
|
| + // Multiple calls do not capture.
|
| + ASSERT_TRUE(callback.Run(true, false) == NULL);
|
| + ASSERT_TRUE(callback.Run(true, false) == NULL);
|
| + EXPECT_EQ(0, deletes);
|
| +
|
| + // Transfer ownership out.
|
| + scoped_ptr<DeleteCounter> result(callback.Run(true, true));
|
| + ASSERT_EQ(counter, result.get());
|
| + EXPECT_EQ(0, deletes);
|
| +
|
| + // Next invocation will find the PassScopedPtr is invalid.
|
| + ASSERT_TRUE(callback.Run(false, false) == NULL);
|
| + EXPECT_EQ(0, deletes);
|
| +
|
| + // Resetting does not delete since ownership was transfered.
|
| + callback.Reset();
|
| + EXPECT_EQ(0, deletes);
|
| +}
|
| +
|
| // Argument Copy-constructor usage for non-reference parameters.
|
| // - Bound arguments are only copied once.
|
| // - Forwarded arguments are only copied once.
|
|
|