Commit 211921f6 authored by akalin@chromium.org's avatar akalin@chromium.org

[Sync] Add type conversion constructor for WeakHandle

This allows the use of e.g.:

WeakHandle<T> weak_handle = MakeWeakHandle(WeakPtr<U>());

as long as U is convertible to T, instead of:

WeakHandle<T> weak_handle = WeakHandle<T>(WeakPtr<U>());

Fix all callers.

BUG=
TEST=


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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110436 0039d316-1c4b-4281-b951-d872f2087c98
parent 84e4772b
...@@ -826,7 +826,7 @@ bool SyncManager::SyncInternal::Init( ...@@ -826,7 +826,7 @@ bool SyncManager::SyncInternal::Init(
// a freed pointer. This is because UI thread is not shut down. // a freed pointer. This is because UI thread is not shut down.
FOR_EACH_OBSERVER(SyncManager::Observer, observers_, FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
OnInitializationComplete( OnInitializationComplete(
WeakHandle<JsBackend>(weak_ptr_factory_.GetWeakPtr()), MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()),
signed_in)); signed_in));
if (!signed_in && !setup_for_test_mode_) if (!signed_in && !setup_for_test_mode_)
......
...@@ -110,7 +110,7 @@ MockJsBackend::MockJsBackend() {} ...@@ -110,7 +110,7 @@ MockJsBackend::MockJsBackend() {}
MockJsBackend::~MockJsBackend() {} MockJsBackend::~MockJsBackend() {}
WeakHandle<JsBackend> MockJsBackend::AsWeakHandle() { WeakHandle<JsBackend> MockJsBackend::AsWeakHandle() {
return WeakHandle<JsBackend>(AsWeakPtr()); return MakeWeakHandle(AsWeakPtr());
} }
MockJsController::MockJsController() {} MockJsController::MockJsController() {}
...@@ -120,7 +120,7 @@ MockJsController::~MockJsController() {} ...@@ -120,7 +120,7 @@ MockJsController::~MockJsController() {}
MockJsEventHandler::MockJsEventHandler() {} MockJsEventHandler::MockJsEventHandler() {}
WeakHandle<JsEventHandler> MockJsEventHandler::AsWeakHandle() { WeakHandle<JsEventHandler> MockJsEventHandler::AsWeakHandle() {
return WeakHandle<JsEventHandler>(AsWeakPtr()); return MakeWeakHandle(AsWeakPtr());
} }
MockJsEventHandler::~MockJsEventHandler() {} MockJsEventHandler::~MockJsEventHandler() {}
...@@ -130,7 +130,7 @@ MockJsReplyHandler::MockJsReplyHandler() {} ...@@ -130,7 +130,7 @@ MockJsReplyHandler::MockJsReplyHandler() {}
MockJsReplyHandler::~MockJsReplyHandler() {} MockJsReplyHandler::~MockJsReplyHandler() {}
WeakHandle<JsReplyHandler> MockJsReplyHandler::AsWeakHandle() { WeakHandle<JsReplyHandler> MockJsReplyHandler::AsWeakHandle() {
return WeakHandle<JsReplyHandler>(AsWeakPtr()); return MakeWeakHandle(AsWeakPtr());
} }
} // namespace browser_sync } // namespace browser_sync
......
...@@ -75,7 +75,7 @@ class ChromeInvalidationClientTest : public testing::Test { ...@@ -75,7 +75,7 @@ class ChromeInvalidationClientTest : public testing::Test {
virtual void SetUp() { virtual void SetUp() {
client_.Start(kClientId, kClientInfo, kState, client_.Start(kClientId, kClientInfo, kState,
InvalidationVersionMap(), InvalidationVersionMap(),
browser_sync::WeakHandle<InvalidationVersionTracker>( browser_sync::MakeWeakHandle(
mock_invalidation_version_tracker_.AsWeakPtr()), mock_invalidation_version_tracker_.AsWeakPtr()),
&mock_listener_, &mock_state_writer_, &mock_listener_, &mock_state_writer_,
fake_base_task_.AsWeakPtr()); fake_base_task_.AsWeakPtr());
......
...@@ -43,7 +43,7 @@ class NonBlockingInvalidationNotifierTest : public testing::Test { ...@@ -43,7 +43,7 @@ class NonBlockingInvalidationNotifierTest : public testing::Test {
new NonBlockingInvalidationNotifier( new NonBlockingInvalidationNotifier(
notifier_options, notifier_options,
InvalidationVersionMap(), InvalidationVersionMap(),
browser_sync::WeakHandle<InvalidationVersionTracker>( browser_sync::MakeWeakHandle(
base::WeakPtr<sync_notifier::InvalidationVersionTracker>()), base::WeakPtr<sync_notifier::InvalidationVersionTracker>()),
"fake_client_info")); "fake_client_info"));
invalidation_notifier_->AddObserver(&mock_observer_); invalidation_notifier_->AddObserver(&mock_observer_);
......
...@@ -311,7 +311,7 @@ void ProfileSyncService::InitializeBackend(bool delete_stale_data) { ...@@ -311,7 +311,7 @@ void ProfileSyncService::InitializeBackend(bool delete_stale_data) {
backend_->Initialize( backend_->Initialize(
this, this,
WeakHandle<JsEventHandler>(sync_js_controller_.AsWeakPtr()), MakeWeakHandle(sync_js_controller_.AsWeakPtr()),
sync_service_url_, sync_service_url_,
initial_types, initial_types,
credentials, credentials,
......
...@@ -74,8 +74,7 @@ void SyncJsController::UpdateBackendEventHandler() { ...@@ -74,8 +74,7 @@ void SyncJsController::UpdateBackendEventHandler() {
// handlers. // handlers.
WeakHandle<JsEventHandler> backend_event_handler = WeakHandle<JsEventHandler> backend_event_handler =
(js_event_handlers_.size() > 0) ? (js_event_handlers_.size() > 0) ?
WeakHandle<JsEventHandler>(AsWeakPtr()) : MakeWeakHandle(AsWeakPtr()) : WeakHandle<SyncJsController>();
WeakHandle<JsEventHandler>();
js_backend_.Call(FROM_HERE, &JsBackend::SetJsEventHandler, js_backend_.Call(FROM_HERE, &JsBackend::SetJsEventHandler,
backend_event_handler); backend_event_handler);
} }
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/location.h" #include "base/location.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
...@@ -280,6 +281,17 @@ class WeakHandle { ...@@ -280,6 +281,17 @@ class WeakHandle {
explicit WeakHandle(const base::WeakPtr<T>& ptr) explicit WeakHandle(const base::WeakPtr<T>& ptr)
: core_(new internal::WeakHandleCore<T>(ptr)) {} : core_(new internal::WeakHandleCore<T>(ptr)) {}
// Allow conversion from WeakHandle<U> to WeakHandle<T> if U is
// convertible to T, but we *must* be on |other|'s owner thread.
// Note that this doesn't override the regular copy constructor, so
// that one can be called on any thread.
template <typename U>
WeakHandle(const browser_sync::WeakHandle<U>& other) // NOLINT
: core_(
other.IsInitialized() ?
new internal::WeakHandleCore<T>(other.Get()) :
NULL) {}
// Returns true iff this WeakHandle is initialized. Note that being // Returns true iff this WeakHandle is initialized. Note that being
// initialized isn't a guarantee that the underlying object is still // initialized isn't a guarantee that the underlying object is still
// alive. // alive.
...@@ -348,6 +360,11 @@ class WeakHandle { ...@@ -348,6 +360,11 @@ class WeakHandle {
} }
private: private:
FRIEND_TEST_ALL_PREFIXES(WeakHandleTest,
TypeConversionConstructor);
FRIEND_TEST_ALL_PREFIXES(WeakHandleTest,
TypeConversionConstructorAssignment);
scoped_refptr<internal::WeakHandleCore<T> > core_; scoped_refptr<internal::WeakHandleCore<T> > core_;
}; };
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace browser_sync { namespace browser_sync {
namespace {
using ::testing::_; using ::testing::_;
using ::testing::SaveArg; using ::testing::SaveArg;
...@@ -44,6 +43,8 @@ class Base { ...@@ -44,6 +43,8 @@ class Base {
base::WeakPtrFactory<Base> weak_ptr_factory_; base::WeakPtrFactory<Base> weak_ptr_factory_;
}; };
class Derived : public Base, public base::SupportsWeakPtr<Derived> {};
class WeakHandleTest : public ::testing::Test { class WeakHandleTest : public ::testing::Test {
protected: protected:
virtual void TearDown() { virtual void TearDown() {
...@@ -260,5 +261,66 @@ TEST_F(WeakHandleTest, InitializedAcrossCopyAssign) { ...@@ -260,5 +261,66 @@ TEST_F(WeakHandleTest, InitializedAcrossCopyAssign) {
PumpLoop(); PumpLoop();
} }
} // namespace TEST_F(WeakHandleTest, TypeConversionConstructor) {
StrictMock<Derived> d;
EXPECT_CALL(d, Test()).Times(2);
const WeakHandle<Derived> weak_handle = MakeWeakHandle(d.AsWeakPtr());
// Should trigger type conversion constructor.
const WeakHandle<Base> base_weak_handle(weak_handle);
// Should trigger regular copy constructor.
const WeakHandle<Derived> derived_weak_handle(weak_handle);
EXPECT_TRUE(base_weak_handle.IsInitialized());
base_weak_handle.Call(FROM_HERE, &Base::Test);
EXPECT_TRUE(derived_weak_handle.IsInitialized());
// Copy constructor shouldn't construct a new |core_|.
EXPECT_EQ(weak_handle.core_.get(), derived_weak_handle.core_.get());
derived_weak_handle.Call(FROM_HERE, &Base::Test);
PumpLoop();
}
TEST_F(WeakHandleTest, TypeConversionConstructorMakeWeakHandle) {
const base::WeakPtr<Derived> weak_ptr;
// Should trigger type conversion constructor after MakeWeakHandle.
WeakHandle<Base> base_weak_handle(MakeWeakHandle(weak_ptr));
// Should trigger regular copy constructor after MakeWeakHandle.
const WeakHandle<Derived> derived_weak_handle(MakeWeakHandle(weak_ptr));
EXPECT_TRUE(base_weak_handle.IsInitialized());
EXPECT_TRUE(derived_weak_handle.IsInitialized());
}
TEST_F(WeakHandleTest, TypeConversionConstructorAssignment) {
const WeakHandle<Derived> weak_handle =
MakeWeakHandle(Derived().AsWeakPtr());
// Should trigger type conversion constructor before the assignment.
WeakHandle<Base> base_weak_handle;
base_weak_handle = weak_handle;
// Should trigger regular copy constructor before the assignment.
WeakHandle<Derived> derived_weak_handle;
derived_weak_handle = weak_handle;
EXPECT_TRUE(base_weak_handle.IsInitialized());
EXPECT_TRUE(derived_weak_handle.IsInitialized());
// Copy constructor shouldn't construct a new |core_|.
EXPECT_EQ(weak_handle.core_.get(), derived_weak_handle.core_.get());
}
TEST_F(WeakHandleTest, TypeConversionConstructorUninitialized) {
const WeakHandle<Base> base_weak_handle = WeakHandle<Derived>();
EXPECT_FALSE(base_weak_handle.IsInitialized());
}
TEST_F(WeakHandleTest, TypeConversionConstructorUninitializedAssignment) {
WeakHandle<Base> base_weak_handle;
base_weak_handle = WeakHandle<Derived>();
EXPECT_FALSE(base_weak_handle.IsInitialized());
}
} // namespace browser_sync } // namespace browser_sync
...@@ -113,7 +113,7 @@ void SyncInternalsUI::OnWebUISend(const GURL& source_url, ...@@ -113,7 +113,7 @@ void SyncInternalsUI::OnWebUISend(const GURL& source_url,
if (js_controller_.get()) { if (js_controller_.get()) {
js_controller_->ProcessJsMessage( js_controller_->ProcessJsMessage(
name, args, name, args,
WeakHandle<JsReplyHandler>(weak_ptr_factory_.GetWeakPtr())); MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()));
} else { } else {
LOG(WARNING) << "No sync service; dropping message " << name LOG(WARNING) << "No sync service; dropping message " << name
<< " with args " << args.ToString(); << " with args " << args.ToString();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment