Commit 5a3788ee authored by Minoru Chikamune's avatar Minoru Chikamune Committed by Commit Bot

Add a mode which doesn't reset the mojo connection when the associated...

Add a mode which doesn't reset the mojo connection when the associated ExecutionContext is detached.

If the original code doesn't have `ContextDestroyed()`, then HeapMojoWrapperMode::kWithoutContextObserver should be used.

Bug: 1058076
Change-Id: I6ea02f1b663b968d70e7b3b475ce40f183592f57
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2114020Reviewed-by: default avatarKeishi Hattori <keishi@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarKouhei Ueno <kouhei@chromium.org>
Commit-Queue: Minoru Chikamune <chikamune@chromium.org>
Cr-Commit-Position: refs/heads/master@{#753122}
parent 772d2084
......@@ -1230,6 +1230,7 @@ jumbo_component("platform") {
"mojo/heap_mojo_receiver_set.h",
"mojo/heap_mojo_remote.h",
"mojo/heap_mojo_unique_receiver_set.h",
"mojo/heap_mojo_wrapper_mode.h",
"mojo/kurl_mojom_traits.h",
"mojo/mojo_helper.h",
"mojo/security_origin_mojom_traits.h",
......
......@@ -8,6 +8,7 @@
#include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/blink/renderer/platform/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
......@@ -17,7 +18,11 @@ namespace blink {
// HeapMojoReceiver's constructor takes context as a mandatory parameter.
// HeapMojoReceiver resets the mojo connection when 1) the owner object is
// garbage-collected and 2) the associated ExecutionContext is detached.
template <typename Interface>
// TODO(crbug.com/1058076) HeapMojoWrapperMode should be removed once we ensure
// that the interface is not used after ContextDestroyed().
template <typename Interface,
HeapMojoWrapperMode Mode = HeapMojoWrapperMode::kWithContextObserver>
class HeapMojoReceiver {
DISALLOW_NEW();
......@@ -72,7 +77,10 @@ class HeapMojoReceiver {
mojo::Receiver<Interface>& receiver() { return receiver_; }
// ContextLifecycleObserver methods
void ContextDestroyed() override { receiver_.reset(); }
void ContextDestroyed() override {
if (Mode == HeapMojoWrapperMode::kWithContextObserver)
receiver_.reset();
}
private:
mojo::Receiver<Interface> receiver_;
......
......@@ -9,6 +9,7 @@
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "third_party/blink/renderer/platform/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
......@@ -18,7 +19,11 @@ namespace blink {
// HeapMojoReceiverSet's constructor takes context as a mandatory parameter.
// HeapMojoReceiverSet resets the mojo connection when 1) the owner object is
// garbage-collected or 2) the associated ExecutionContext is detached.
template <typename Interface>
// TODO(crbug.com/1058076) HeapMojoWrapperMode should be removed once we ensure
// that the interface is not used after ContextDestroyed().
template <typename Interface,
HeapMojoWrapperMode Mode = HeapMojoWrapperMode::kWithContextObserver>
class HeapMojoReceiverSet {
DISALLOW_NEW();
......@@ -72,10 +77,13 @@ class HeapMojoReceiverSet {
mojo::ReceiverSet<Interface>& receiver_set() { return receiver_set_; }
// ContextLifecycleObserver methods
void ContextDestroyed() override { receiver_set_.Clear(); }
void ContextDestroyed() override {
if (Mode == HeapMojoWrapperMode::kWithContextObserver)
receiver_set_.Clear();
}
private:
::mojo::ReceiverSet<Interface> receiver_set_;
mojo::ReceiverSet<Interface> receiver_set_;
};
Member<Wrapper> wrapper_;
......
......@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/heap_observer_list.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
......@@ -60,47 +61,56 @@ class MockService : public sample::blink::Service {
void GetPort(mojo::PendingReceiver<sample::blink::Port> receiver) override {}
};
class GCOwner : public GarbageCollected<GCOwner> {
template <HeapMojoWrapperMode Mode>
class GCOwner : public GarbageCollected<GCOwner<Mode>> {
public:
explicit GCOwner(FakeContextNotifier* context) : receiver_set_(context) {}
void Trace(Visitor* visitor) { visitor->Trace(receiver_set_); }
HeapMojoReceiverSet<sample::blink::Service>& receiver_set() {
HeapMojoReceiverSet<sample::blink::Service, Mode>& receiver_set() {
return receiver_set_;
}
private:
HeapMojoReceiverSet<sample::blink::Service> receiver_set_;
HeapMojoReceiverSet<sample::blink::Service, Mode> receiver_set_;
};
} // namespace
class HeapMojoReceiverSetTest : public TestSupportingGC {
template <HeapMojoWrapperMode Mode>
class HeapMojoReceiverSetGCBaseTest : public TestSupportingGC {
public:
FakeContextNotifier* context() { return context_; }
scoped_refptr<base::NullTaskRunner> task_runner() {
return null_task_runner_;
}
GCOwner* owner() { return owner_; }
GCOwner<Mode>* owner() { return owner_; }
void ClearOwner() { owner_ = nullptr; }
protected:
void SetUp() override {
context_ = MakeGarbageCollected<FakeContextNotifier>();
owner_ = MakeGarbageCollected<GCOwner>(context());
owner_ = MakeGarbageCollected<GCOwner<Mode>>(context());
}
void TearDown() override {}
Persistent<FakeContextNotifier> context_;
Persistent<GCOwner> owner_;
Persistent<GCOwner<Mode>> owner_;
scoped_refptr<base::NullTaskRunner> null_task_runner_ =
base::MakeRefCounted<base::NullTaskRunner>();
};
// GC the HeapMojoReceiverSet and verify that the receiver is no longer
// part of the set, and that the service was deleted.
TEST_F(HeapMojoReceiverSetTest, RemovesReceiver) {
} // namespace
class HeapMojoReceiverSetGCWithContextObserverTest
: public HeapMojoReceiverSetGCBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoReceiverSetGCWithoutContextObserverTest
: public HeapMojoReceiverSetGCBaseTest<
HeapMojoWrapperMode::kWithoutContextObserver> {};
// GC the HeapMojoReceiverSet with context observer and verify that the receiver
// is no longer part of the set, and that the service was deleted.
TEST_F(HeapMojoReceiverSetGCWithContextObserverTest, RemovesReceiver) {
auto receiver_set = owner()->receiver_set();
MockService service;
auto receiver = mojo::PendingReceiver<sample::blink::Service>(
......@@ -115,7 +125,43 @@ TEST_F(HeapMojoReceiverSetTest, RemovesReceiver) {
EXPECT_FALSE(receiver_set.HasReceiver(rid));
}
TEST_F(HeapMojoReceiverSetTest, ClearLeavesSetEmpty) {
// GC the HeapMojoReceiverSet without context observer and verify that the
// receiver is no longer part of the set, and that the service was deleted.
TEST_F(HeapMojoReceiverSetGCWithoutContextObserverTest, RemovesReceiver) {
auto receiver_set = owner()->receiver_set();
MockService service;
auto receiver = mojo::PendingReceiver<sample::blink::Service>(
mojo::MessagePipe().handle0);
mojo::ReceiverId rid =
receiver_set.Add(&service, std::move(receiver), task_runner());
EXPECT_TRUE(receiver_set.HasReceiver(rid));
receiver_set.Remove(rid);
EXPECT_FALSE(receiver_set.HasReceiver(rid));
}
// GC the HeapMojoReceiverSet with context observer and verify that the receiver
// is no longer part of the set, and that the service was deleted.
TEST_F(HeapMojoReceiverSetGCWithContextObserverTest, ClearLeavesSetEmpty) {
auto receiver_set = owner()->receiver_set();
MockService service;
auto receiver = mojo::PendingReceiver<sample::blink::Service>(
mojo::MessagePipe().handle0);
mojo::ReceiverId rid =
receiver_set.Add(&service, std::move(receiver), task_runner());
EXPECT_TRUE(receiver_set.HasReceiver(rid));
receiver_set.Clear();
EXPECT_FALSE(receiver_set.HasReceiver(rid));
}
// GC the HeapMojoReceiverSet without context observer and verify that the
// receiver is no longer part of the set, and that the service was deleted.
TEST_F(HeapMojoReceiverSetGCWithoutContextObserverTest, ClearLeavesSetEmpty) {
auto receiver_set = owner()->receiver_set();
MockService service;
auto receiver = mojo::PendingReceiver<sample::blink::Service>(
......
......@@ -8,9 +8,12 @@
#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/heap_observer_list.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
namespace {
class MockContext final : public GarbageCollected<MockContext>,
public ContextLifecycleNotifier {
USING_GARBAGE_COLLECTED_MIXIN(MockContext);
......@@ -42,12 +45,15 @@ class MockContext final : public GarbageCollected<MockContext>,
HeapObserverList<ContextLifecycleObserver> observers_;
};
class ReceiverOwner : public GarbageCollected<ReceiverOwner>,
template <HeapMojoWrapperMode Mode>
class ReceiverOwner : public GarbageCollected<ReceiverOwner<Mode>>,
public sample::blink::Service {
public:
explicit ReceiverOwner(MockContext* context) : receiver_(this, context) {}
HeapMojoReceiver<sample::blink::Service>& receiver() { return receiver_; }
HeapMojoReceiver<sample::blink::Service, Mode>& receiver() {
return receiver_;
}
void Trace(Visitor* visitor) { visitor->Trace(receiver_); }
......@@ -59,10 +65,11 @@ class ReceiverOwner : public GarbageCollected<ReceiverOwner>,
sample::blink::Service::FrobinateCallback callback) override {}
void GetPort(mojo::PendingReceiver<sample::blink::Port> port) override {}
HeapMojoReceiver<sample::blink::Service> receiver_;
HeapMojoReceiver<sample::blink::Service, Mode> receiver_;
};
class HeapMojoReceiverTest : public TestSupportingGC {
template <HeapMojoWrapperMode Mode>
class HeapMojoReceiverGCBaseTest : public TestSupportingGC {
public:
base::RunLoop& run_loop() { return run_loop_; }
bool& disconnected() { return disconnected_; }
......@@ -73,13 +80,13 @@ class HeapMojoReceiverTest : public TestSupportingGC {
void SetUp() override {
CHECK(!disconnected_);
context_ = MakeGarbageCollected<MockContext>();
owner_ = MakeGarbageCollected<ReceiverOwner>(context_);
owner_ = MakeGarbageCollected<ReceiverOwner<Mode>>(context_);
scoped_refptr<base::NullTaskRunner> null_task_runner =
base::MakeRefCounted<base::NullTaskRunner>();
remote_ = mojo::Remote<sample::blink::Service>(
owner_->receiver().BindNewPipeAndPassRemote(null_task_runner));
remote_.set_disconnect_handler(WTF::Bind(
[](HeapMojoReceiverTest* receiver_test) {
[](HeapMojoReceiverGCBaseTest* receiver_test) {
receiver_test->run_loop().Quit();
receiver_test->disconnected() = true;
},
......@@ -88,29 +95,82 @@ class HeapMojoReceiverTest : public TestSupportingGC {
void TearDown() override { CHECK(disconnected_); }
Persistent<MockContext> context_;
Persistent<ReceiverOwner> owner_;
Persistent<ReceiverOwner<Mode>> owner_;
base::RunLoop run_loop_;
mojo::Remote<sample::blink::Service> remote_;
bool disconnected_ = false;
};
// Make HeapMojoReceiver garbage collected and check that the connection is
// disconnected right after the marking phase.
TEST_F(HeapMojoReceiverTest, ResetsOnGC) {
template <HeapMojoWrapperMode Mode>
class HeapMojoReceiverDestroyContextBaseTest : public TestSupportingGC {
protected:
void SetUp() override {
context_ = MakeGarbageCollected<MockContext>();
owner_ = MakeGarbageCollected<ReceiverOwner<Mode>>(context_);
scoped_refptr<base::NullTaskRunner> null_task_runner =
base::MakeRefCounted<base::NullTaskRunner>();
remote_ = mojo::Remote<sample::blink::Service>(
owner_->receiver().BindNewPipeAndPassRemote(null_task_runner));
}
Persistent<MockContext> context_;
Persistent<ReceiverOwner<Mode>> owner_;
mojo::Remote<sample::blink::Service> remote_;
};
} // namespace
class HeapMojoReceiverGCWithContextObserverTest
: public HeapMojoReceiverGCBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoReceiverGCWithoutContextObserverTest
: public HeapMojoReceiverGCBaseTest<
HeapMojoWrapperMode::kWithoutContextObserver> {};
class HeapMojoReceiverDestroyContextWithContextObserverTest
: public HeapMojoReceiverDestroyContextBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoReceiverDestroyContextWithoutContextObserverTest
: public HeapMojoReceiverDestroyContextBaseTest<
HeapMojoWrapperMode::kWithoutContextObserver> {};
// Make HeapMojoReceiver with context observer garbage collected and check that
// the connection is disconnected right after the marking phase.
TEST_F(HeapMojoReceiverGCWithContextObserverTest, ResetsOnGC) {
ClearOwner();
EXPECT_FALSE(disconnected());
PreciselyCollectGarbage(BlinkGC::kConcurrentAndLazySweeping);
PreciselyCollectGarbage();
run_loop().Run();
EXPECT_TRUE(disconnected());
CompleteSweepingIfNeeded();
}
// Destroy the context and check that the connection is disconnected.
TEST_F(HeapMojoReceiverTest, ResetsOnContextDestroyed) {
// Make HeapMojoReceiver without context observer garbage collected and check
// that the connection is disconnected right after the marking phase.
TEST_F(HeapMojoReceiverGCWithoutContextObserverTest, ResetsOnGC) {
ClearOwner();
EXPECT_FALSE(disconnected());
context_->NotifyContextDestroyed();
PreciselyCollectGarbage();
run_loop().Run();
EXPECT_TRUE(disconnected());
CompleteSweepingIfNeeded();
}
// Destroy the context with context observer and check that the connection is
// disconnected.
TEST_F(HeapMojoReceiverDestroyContextWithContextObserverTest,
ResetsOnContextDestroyed) {
EXPECT_TRUE(owner_->receiver().is_bound());
context_->NotifyContextDestroyed();
EXPECT_FALSE(owner_->receiver().is_bound());
}
// Destroy the context without context observer and check that the connection is
// still connected.
TEST_F(HeapMojoReceiverDestroyContextWithoutContextObserverTest,
ResetsOnContextDestroyed) {
EXPECT_TRUE(owner_->receiver().is_bound());
context_->NotifyContextDestroyed();
EXPECT_TRUE(owner_->receiver().is_bound());
}
} // namespace blink
......@@ -10,6 +10,7 @@
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/renderer/platform/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
......@@ -19,7 +20,11 @@ namespace blink {
// HeapMojoRemote's constructor takes context as a mandatory parameter.
// HeapMojoRemote resets the mojo connection when 1) the owner object is
// garbage-collected and 2) the associated ExecutionContext is detached.
template <typename Interface>
// TODO(crbug.com/1058076) HeapMojoWrapperMode should be removed once we ensure
// that the interface is not used after ContextDestroyed().
template <typename Interface,
HeapMojoWrapperMode Mode = HeapMojoWrapperMode::kWithContextObserver>
class HeapMojoRemote {
DISALLOW_NEW();
......@@ -72,7 +77,10 @@ class HeapMojoRemote {
mojo::Remote<Interface>& remote() { return remote_; }
// ContextLifecycleObserver methods
void ContextDestroyed() override { remote_.reset(); }
void ContextDestroyed() override {
if (Mode == HeapMojoWrapperMode::kWithContextObserver)
remote_.reset();
}
private:
mojo::Remote<Interface> remote_;
......
......@@ -8,9 +8,12 @@
#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/heap_observer_list.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
namespace {
class MockContext final : public GarbageCollected<MockContext>,
public ContextLifecycleNotifier {
USING_GARBAGE_COLLECTED_MIXIN(MockContext);
......@@ -59,18 +62,20 @@ class ServiceImpl : public sample::blink::Service {
mojo::Receiver<sample::blink::Service> receiver_{this};
};
class RemoteOwner : public GarbageCollected<RemoteOwner> {
template <HeapMojoWrapperMode Mode>
class RemoteOwner : public GarbageCollected<RemoteOwner<Mode>> {
public:
explicit RemoteOwner(MockContext* context) : remote_(context) {}
HeapMojoRemote<sample::blink::Service>& remote() { return remote_; }
HeapMojoRemote<sample::blink::Service, Mode>& remote() { return remote_; }
void Trace(Visitor* visitor) { visitor->Trace(remote_); }
HeapMojoRemote<sample::blink::Service> remote_;
HeapMojoRemote<sample::blink::Service, Mode> remote_;
};
class HeapMojoRemoteTest : public TestSupportingGC {
template <HeapMojoWrapperMode Mode>
class HeapMojoRemoteGCBaseTest : public TestSupportingGC {
public:
base::RunLoop& run_loop() { return run_loop_; }
bool& disconnected() { return disconnected_; }
......@@ -81,46 +86,96 @@ class HeapMojoRemoteTest : public TestSupportingGC {
void SetUp() override {
CHECK(!disconnected_);
context_ = MakeGarbageCollected<MockContext>();
owner_ = MakeGarbageCollected<RemoteOwner>(context_);
owner_ = MakeGarbageCollected<RemoteOwner<Mode>>(context_);
scoped_refptr<base::NullTaskRunner> null_task_runner =
base::MakeRefCounted<base::NullTaskRunner>();
impl_.receiver().Bind(
owner_->remote().BindNewPipeAndPassReceiver(null_task_runner));
impl_.receiver().set_disconnect_handler(WTF::Bind(
[](HeapMojoRemoteTest* remote_test) {
[](HeapMojoRemoteGCBaseTest* remote_test) {
remote_test->run_loop().Quit();
remote_test->disconnected() = true;
},
WTF::Unretained(this)));
}
void TearDown() override {
// CHECK(disconnected_);
}
ServiceImpl impl_;
Persistent<MockContext> context_;
Persistent<RemoteOwner> owner_;
Persistent<RemoteOwner<Mode>> owner_;
base::RunLoop run_loop_;
bool disconnected_ = false;
};
// Make HeapMojoRemote garbage collected and check that the connection is
// disconnected right after the marking phase.
TEST_F(HeapMojoRemoteTest, ResetsOnGC) {
template <HeapMojoWrapperMode Mode>
class HeapMojoRemoteDestroyContextBaseTest : public TestSupportingGC {
protected:
void SetUp() override {
context_ = MakeGarbageCollected<MockContext>();
owner_ = MakeGarbageCollected<RemoteOwner<Mode>>(context_);
scoped_refptr<base::NullTaskRunner> null_task_runner =
base::MakeRefCounted<base::NullTaskRunner>();
impl_.receiver().Bind(
owner_->remote().BindNewPipeAndPassReceiver(null_task_runner));
}
ServiceImpl impl_;
Persistent<MockContext> context_;
Persistent<RemoteOwner<Mode>> owner_;
};
} // namespace
class HeapMojoRemoteGCWithContextObserverTest
: public HeapMojoRemoteGCBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoRemoteGCWithoutContextObserverTest
: public HeapMojoRemoteGCBaseTest<
HeapMojoWrapperMode::kWithoutContextObserver> {};
class HeapMojoRemoteDestroyContextWithContextObserverTest
: public HeapMojoRemoteDestroyContextBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoRemoteDestroyContextWithoutContextObserverTest
: public HeapMojoRemoteDestroyContextBaseTest<
HeapMojoWrapperMode::kWithoutContextObserver> {};
// Make HeapMojoRemote with context observer garbage collected and check that
// the connection is disconnected right after the marking phase.
TEST_F(HeapMojoRemoteGCWithContextObserverTest, ResetsOnGC) {
ClearOwner();
EXPECT_FALSE(disconnected());
PreciselyCollectGarbage(BlinkGC::kConcurrentAndLazySweeping);
PreciselyCollectGarbage();
run_loop().Run();
EXPECT_TRUE(disconnected());
CompleteSweepingIfNeeded();
}
// Destroy the context and check that the connection is disconnected.
TEST_F(HeapMojoRemoteTest, ResetsOnContextDestroyed) {
// Make HeapMojoRemote without context observer garbage collected and check that
// the connection is disconnected right after the marking phase.
TEST_F(HeapMojoRemoteGCWithoutContextObserverTest, ResetsOnGC) {
ClearOwner();
EXPECT_FALSE(disconnected());
context_->NotifyContextDestroyed();
PreciselyCollectGarbage();
run_loop().Run();
EXPECT_TRUE(disconnected());
CompleteSweepingIfNeeded();
}
// Destroy the context with context observer and check that the connection is
// disconnected.
TEST_F(HeapMojoRemoteDestroyContextWithContextObserverTest,
ResetsOnContextDestroyed) {
EXPECT_TRUE(owner_->remote().is_bound());
context_->NotifyContextDestroyed();
EXPECT_FALSE(owner_->remote().is_bound());
}
// Destroy the context without context observer and check that the connection is
// still connected.
TEST_F(HeapMojoRemoteDestroyContextWithoutContextObserverTest,
ResetsOnContextDestroyed) {
EXPECT_TRUE(owner_->remote().is_bound());
context_->NotifyContextDestroyed();
EXPECT_TRUE(owner_->remote().is_bound());
}
} // namespace blink
......@@ -9,6 +9,7 @@
#include "mojo/public/cpp/bindings/unique_receiver_set.h"
#include "third_party/blink/renderer/platform/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
......@@ -19,7 +20,9 @@ namespace blink {
// context as a mandatory parameter. HeapMojoUniqueReceiverSet resets the mojo
// connection when 1) the owner object is garbage-collected or 2) the associated
// ExecutionContext is detached.
template <typename Interface, typename Deleter = std::default_delete<Interface>>
template <typename Interface,
typename Deleter = std::default_delete<Interface>,
HeapMojoWrapperMode Mode = HeapMojoWrapperMode::kWithContextObserver>
class HeapMojoUniqueReceiverSet {
DISALLOW_NEW();
......@@ -76,7 +79,10 @@ class HeapMojoUniqueReceiverSet {
}
// ContextLifecycleObserver methods
void ContextDestroyed() override { receiver_set_.Clear(); }
void ContextDestroyed() override {
if (Mode == HeapMojoWrapperMode::kWithContextObserver)
receiver_set_.Clear();
}
private:
mojo::UniqueReceiverSet<Interface, void, Deleter> receiver_set_;
......
......@@ -11,10 +11,12 @@
#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/heap_observer_list.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
namespace {
class FakeContextNotifier final : public GarbageCollected<FakeContextNotifier>,
public ContextLifecycleNotifier {
USING_GARBAGE_COLLECTED_MIXIN(FakeContextNotifier);
......@@ -46,27 +48,34 @@ class FakeContextNotifier final : public GarbageCollected<FakeContextNotifier>,
HeapObserverList<ContextLifecycleObserver> observers_;
};
class GCOwner : public GarbageCollected<GCOwner> {
template <HeapMojoWrapperMode Mode>
class GCOwner : public GarbageCollected<GCOwner<Mode>> {
public:
explicit GCOwner(FakeContextNotifier* context) : receiver_set_(context) {}
void Trace(Visitor* visitor) { visitor->Trace(receiver_set_); }
HeapMojoUniqueReceiverSet<sample::blink::Service>& receiver_set() {
HeapMojoUniqueReceiverSet<sample::blink::Service,
std::default_delete<sample::blink::Service>,
Mode>&
receiver_set() {
return receiver_set_;
}
private:
HeapMojoUniqueReceiverSet<sample::blink::Service> receiver_set_;
HeapMojoUniqueReceiverSet<sample::blink::Service,
std::default_delete<sample::blink::Service>,
Mode>
receiver_set_;
};
} // namespace
class HeapMojoUniqueReceiverSetTest : public TestSupportingGC {
template <HeapMojoWrapperMode Mode>
class HeapMojoUniqueReceiverSetBaseTest : public TestSupportingGC {
public:
FakeContextNotifier* context() { return context_; }
scoped_refptr<base::NullTaskRunner> task_runner() {
return null_task_runner_;
}
GCOwner* owner() { return owner_; }
GCOwner<Mode>* owner() { return owner_; }
void ClearOwner() { owner_ = nullptr; }
......@@ -75,22 +84,32 @@ class HeapMojoUniqueReceiverSetTest : public TestSupportingGC {
protected:
void SetUp() override {
context_ = MakeGarbageCollected<FakeContextNotifier>();
owner_ = MakeGarbageCollected<GCOwner>(context());
owner_ = MakeGarbageCollected<GCOwner<Mode>>(context());
}
void TearDown() override {}
Persistent<FakeContextNotifier> context_;
Persistent<GCOwner> owner_;
Persistent<GCOwner<Mode>> owner_;
scoped_refptr<base::NullTaskRunner> null_task_runner_ =
base::MakeRefCounted<base::NullTaskRunner>();
bool service_deleted_ = false;
};
class HeapMojoUniqueReceiverSetWithContextObserverTest
: public HeapMojoUniqueReceiverSetBaseTest<
HeapMojoWrapperMode::kWithContextObserver> {};
class HeapMojoUniqueReceiverSetWithoutContextObserverTest
: public HeapMojoUniqueReceiverSetBaseTest<
HeapMojoWrapperMode::kWithoutContextObserver> {};
} // namespace
namespace {
template <typename T>
class MockService : public sample::blink::Service {
public:
explicit MockService(HeapMojoUniqueReceiverSetTest* test) : test_(test) {}
explicit MockService(T* test) : test_(test) {}
// Notify the test when the service is deleted by the UniqueReceiverSet.
~MockService() override { test_->MarkServiceDeleted(); }
......@@ -101,16 +120,39 @@ class MockService : public sample::blink::Service {
void GetPort(mojo::PendingReceiver<sample::blink::Port> receiver) override {}
private:
HeapMojoUniqueReceiverSetTest* test_;
T* test_;
};
} // namespace
// GC the HeapMojoUniqueReceiverSet and verify that the receiver is no longer
// part of the set, and that the service was deleted.
TEST_F(HeapMojoUniqueReceiverSetTest, ResetsOnGC) {
// GC the HeapMojoUniqueReceiverSet with context observer and verify that the
// receiver is no longer part of the set, and that the service was deleted.
TEST_F(HeapMojoUniqueReceiverSetWithContextObserverTest, ResetsOnGC) {
auto receiver_set = owner()->receiver_set();
auto service = std::make_unique<
MockService<HeapMojoUniqueReceiverSetWithContextObserverTest>>(this);
auto receiver = mojo::PendingReceiver<sample::blink::Service>(
mojo::MessagePipe().handle0);
mojo::ReceiverId rid =
receiver_set.Add(std::move(service), std::move(receiver), task_runner());
EXPECT_TRUE(receiver_set.HasReceiver(rid));
EXPECT_FALSE(service_deleted_);
ClearOwner();
PreciselyCollectGarbage();
EXPECT_TRUE(service_deleted_);
CompleteSweepingIfNeeded();
}
// GC the HeapMojoUniqueReceiverSet without context observer and verify that the
// receiver is no longer part of the set, and that the service was deleted.
TEST_F(HeapMojoUniqueReceiverSetWithoutContextObserverTest, ResetsOnGC) {
auto receiver_set = owner()->receiver_set();
auto service = std::make_unique<MockService>(this);
auto service = std::make_unique<
MockService<HeapMojoUniqueReceiverSetWithoutContextObserverTest>>(this);
auto receiver = mojo::PendingReceiver<sample::blink::Service>(
mojo::MessagePipe().handle0);
......@@ -120,18 +162,41 @@ TEST_F(HeapMojoUniqueReceiverSetTest, ResetsOnGC) {
EXPECT_FALSE(service_deleted_);
ClearOwner();
PreciselyCollectGarbage(BlinkGC::kConcurrentAndLazySweeping);
PreciselyCollectGarbage();
EXPECT_TRUE(service_deleted_);
CompleteSweepingIfNeeded();
}
// Destroy the context and verify that the receiver is no longer
// part of the set, and that the service was deleted.
TEST_F(HeapMojoUniqueReceiverSetTest, ResetsOnContextDestroyed) {
// Destroy the context with context observer and verify that the receiver is no
// longer part of the set, and that the service was deleted.
TEST_F(HeapMojoUniqueReceiverSetWithContextObserverTest,
ResetsOnContextDestroyed) {
HeapMojoUniqueReceiverSet<sample::blink::Service> receiver_set(context());
auto service = std::make_unique<
MockService<HeapMojoUniqueReceiverSetWithContextObserverTest>>(this);
auto receiver = mojo::PendingReceiver<sample::blink::Service>(
mojo::MessagePipe().handle0);
mojo::ReceiverId rid =
receiver_set.Add(std::move(service), std::move(receiver), task_runner());
EXPECT_TRUE(receiver_set.HasReceiver(rid));
EXPECT_FALSE(service_deleted_);
context_->NotifyContextDestroyed();
EXPECT_FALSE(receiver_set.HasReceiver(rid));
EXPECT_TRUE(service_deleted_);
}
// Destroy the context without context observer and verify that the receiver is
// no longer part of the set, and that the service was deleted.
TEST_F(HeapMojoUniqueReceiverSetWithoutContextObserverTest,
ResetsOnContextDestroyed) {
HeapMojoUniqueReceiverSet<sample::blink::Service> receiver_set(context());
auto service = std::make_unique<MockService>(this);
auto service = std::make_unique<
MockService<HeapMojoUniqueReceiverSetWithoutContextObserverTest>>(this);
auto receiver = mojo::PendingReceiver<sample::blink::Service>(
mojo::MessagePipe().handle0);
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_WRAPPER_MODE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_WRAPPER_MODE_H_
namespace blink {
// A list of modes for HeapMojo wrappers.
enum class HeapMojoWrapperMode {
// Resets the mojo connection when 1) the owner object is garbage-collected
// and 2) the associated ExecutionContext is detached.
kWithContextObserver,
// Resets the mojo connection when the owner object is garbage-collected.
// But, it will not reset the mojo connection when the associated
// ExecutionContext is detached.
kWithoutContextObserver,
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_WRAPPER_MODE_H_
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