Commit 3f9ef169 authored by yzshen's avatar yzshen Committed by Commit bot

Mojo C++ bindings: make StrongBinding a message loop destruction observer.

This is a preparation for removing message loop destruction observer from mojo::Watcher.

BUG=604762

Review URL: https://codereview.chromium.org/1913333002

Cr-Commit-Position: refs/heads/master@{#389803}
parent fafc5a0d
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <vector> #include <vector>
#include "base/bind.h" #include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "ipc/ipc_channel.h" #include "ipc/ipc_channel.h"
#include "skia/public/type_converters.h" #include "skia/public/type_converters.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -57,10 +58,17 @@ class Request { ...@@ -57,10 +58,17 @@ class Request {
skia::mojom::BitmapPtr bitmap_; skia::mojom::BitmapPtr bitmap_;
}; };
class ImageDecoderImplTest : public testing::Test {
protected:
~ImageDecoderImplTest() override {}
base::MessageLoop message_loop_;
};
} // namespace } // namespace
// Test that DecodeImage() doesn't return image message > (max message size) // Test that DecodeImage() doesn't return image message > (max message size)
TEST(ImageDecoderImplTest, DecodeImageSizeLimit) { TEST_F(ImageDecoderImplTest, DecodeImageSizeLimit) {
// Using actual limit generates 14000 x 9400 images, which causes the test to // Using actual limit generates 14000 x 9400 images, which causes the test to
// timeout. We test with a smaller limit for efficiency. // timeout. We test with a smaller limit for efficiency.
const size_t kTestMessageSize = IPC::Channel::kMaximumMessageSize / 1024; const size_t kTestMessageSize = IPC::Channel::kMaximumMessageSize / 1024;
...@@ -106,7 +114,7 @@ TEST(ImageDecoderImplTest, DecodeImageSizeLimit) { ...@@ -106,7 +114,7 @@ TEST(ImageDecoderImplTest, DecodeImageSizeLimit) {
} }
} }
TEST(ImageDecoderImplTest, DecodeImageFailed) { TEST_F(ImageDecoderImplTest, DecodeImageFailed) {
ImageDecoderImpl decoder(IPC::Channel::kMaximumMessageSize); ImageDecoderImpl decoder(IPC::Channel::kMaximumMessageSize);
// The "jpeg" is just some "random" data; // The "jpeg" is just some "random" data;
......
...@@ -8,20 +8,18 @@ ...@@ -8,20 +8,18 @@
#include <utility> #include <utility>
#include "base/logging.h" #include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/callback.h" #include "mojo/public/cpp/bindings/callback.h"
#include "mojo/public/cpp/bindings/interface_ptr.h" #include "mojo/public/cpp/bindings/interface_ptr.h"
#include "mojo/public/cpp/bindings/interface_request.h" #include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/lib/filter_chain.h"
#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
#include "mojo/public/cpp/bindings/lib/router.h"
#include "mojo/public/cpp/system/core.h" #include "mojo/public/cpp/system/core.h"
namespace mojo { namespace mojo {
// This connects an interface implementation strongly to a pipe. When a // This connects an interface implementation strongly to a pipe. When a
// connection error is detected the implementation is deleted. Deleting the // connection error is detected or the current message loop is destructed the
// connector also closes the pipe. // implementation is deleted.
// //
// Example of an implementation that is always bound strongly to a pipe // Example of an implementation that is always bound strongly to a pipe
// //
...@@ -47,11 +45,13 @@ namespace mojo { ...@@ -47,11 +45,13 @@ namespace mojo {
// This class is thread hostile once it is bound to a message pipe. Until it is // This class is thread hostile once it is bound to a message pipe. Until it is
// bound, it may be bound or destroyed on any thread. // bound, it may be bound or destroyed on any thread.
template <typename Interface> template <typename Interface>
class StrongBinding { class StrongBinding : public base::MessageLoop::DestructionObserver {
MOVE_ONLY_TYPE_FOR_CPP_03(StrongBinding); MOVE_ONLY_TYPE_FOR_CPP_03(StrongBinding);
public: public:
explicit StrongBinding(Interface* impl) : binding_(impl) {} explicit StrongBinding(Interface* impl) : binding_(impl), observing_(true) {
base::MessageLoop::current()->AddDestructionObserver(this);
}
StrongBinding(Interface* impl, ScopedMessagePipeHandle handle) StrongBinding(Interface* impl, ScopedMessagePipeHandle handle)
: StrongBinding(impl) { : StrongBinding(impl) {
...@@ -68,7 +68,7 @@ class StrongBinding { ...@@ -68,7 +68,7 @@ class StrongBinding {
Bind(std::move(request)); Bind(std::move(request));
} }
~StrongBinding() {} ~StrongBinding() override { StopObservingIfNecessary(); }
void Bind(ScopedMessagePipeHandle handle) { void Bind(ScopedMessagePipeHandle handle) {
DCHECK(!binding_.is_bound()); DCHECK(!binding_.is_bound());
...@@ -101,18 +101,31 @@ class StrongBinding { ...@@ -101,18 +101,31 @@ class StrongBinding {
connection_error_handler_ = error_handler; connection_error_handler_ = error_handler;
} }
Interface* impl() { return binding_.impl(); }
// Exposed for testing, should not generally be used.
internal::Router* internal_router() { return binding_.internal_router(); }
void OnConnectionError() { void OnConnectionError() {
StopObservingIfNecessary();
connection_error_handler_.Run(); connection_error_handler_.Run();
delete binding_.impl(); delete binding_.impl();
} }
// base::MessageLoop::DestructionObserver:
void WillDestroyCurrentMessageLoop() override {
StopObservingIfNecessary();
binding_.Close();
delete binding_.impl();
}
private: private:
void StopObservingIfNecessary() {
if (observing_) {
observing_ = false;
base::MessageLoop::current()->RemoveDestructionObserver(this);
}
}
Closure connection_error_handler_; Closure connection_error_handler_;
Binding<Interface> binding_; Binding<Interface> binding_;
// Whether the object is observing message loop destruction.
bool observing_;
}; };
} // namespace mojo } // namespace mojo
......
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