diff options
author | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-21 00:55:17 +0000 |
---|---|---|
committer | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-21 00:55:17 +0000 |
commit | cc01a50a8c541aa7abd19ee9cc584436e5d0690b (patch) | |
tree | d398dd25f9a66a579e23665c00caa7121e85d077 /mojo | |
parent | 539fc831704615b41d69902b8588117cbde1cd28 (diff) | |
download | chromium_src-cc01a50a8c541aa7abd19ee9cc584436e5d0690b.zip chromium_src-cc01a50a8c541aa7abd19ee9cc584436e5d0690b.tar.gz chromium_src-cc01a50a8c541aa7abd19ee9cc584436e5d0690b.tar.bz2 |
Mojo: Improved C++ wrappers.
These build in some stronger static typing and try to help with lifetime
management. They remain true to the C API (using functions instead of
methods), to be consistent and avoid awkwardness between the Handle
objects and their scoped versions (e.g., if we put methods on
MessagePipeHandle, it'd be awkward to access them from the scoped
version).
Also, they are written with code generators in mind. As such, currently
I only provide WriteMessageRaw()/ReadMessageRaw() that a) provide full
access to the C API, and b) don't help with lifetime management (but
also don't impose any further efficiency issues either). I'd consider
adding non-raw versions, but the intention is that most people would use
generated proxy code (which may take, e.g., MessagePipeHandle or
ScopedMessagePipeHandle arguments).
R=abarth@chromium.org, darin@chromium.org
Review URL: https://codereview.chromium.org/71613005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@236357 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo')
37 files changed, 713 insertions, 319 deletions
diff --git a/mojo/apps/js/main.cc b/mojo/apps/js/main.cc index 1d5e896..322c216 100644 --- a/mojo/apps/js/main.cc +++ b/mojo/apps/js/main.cc @@ -3,7 +3,7 @@ // found in the LICENSE file. #include "gin/gin.h" -#include "mojo/public/system/core.h" +#include "mojo/public/system/core_cpp.h" #include "mojo/public/system/macros.h" #if defined(WIN32) @@ -16,8 +16,7 @@ #define MOJO_APPS_JS_EXPORT __attribute__((visibility("default"))) #endif -extern "C" MOJO_APPS_JS_EXPORT MojoResult CDECL MojoMain( - mojo::Handle pipe) { +extern "C" MOJO_APPS_JS_EXPORT MojoResult CDECL MojoMain(MojoHandle pipe) { gin::Gin instance; // TODO(abarth): Load JS off the network and execute it. return MOJO_RESULT_OK; diff --git a/mojo/common/bindings_support_impl.cc b/mojo/common/bindings_support_impl.cc index 9cec141..178fa66 100644 --- a/mojo/common/bindings_support_impl.cc +++ b/mojo/common/bindings_support_impl.cc @@ -39,14 +39,14 @@ BindingsSupportImpl::~BindingsSupportImpl() { } BindingsSupport::AsyncWaitID BindingsSupportImpl::AsyncWait( - Handle handle, + const Handle& handle, MojoWaitFlags flags, AsyncWaitCallback* callback) { // This instance will be deleted when done or cancelled. HandleWatcher* watcher = new HandleWatcher(); // TODO(darin): Standardize on mojo::Handle instead of MojoHandle? - watcher->Start(handle.value, + watcher->Start(handle.value(), flags, MOJO_DEADLINE_INDEFINITE, base::Bind(&Context::CallOnHandleReady, diff --git a/mojo/common/bindings_support_impl.h b/mojo/common/bindings_support_impl.h index 1178644..8b1d08c 100644 --- a/mojo/common/bindings_support_impl.h +++ b/mojo/common/bindings_support_impl.h @@ -22,7 +22,7 @@ class MOJO_COMMON_EXPORT BindingsSupportImpl virtual ~BindingsSupportImpl(); // BindingsSupport methods: - virtual AsyncWaitID AsyncWait(Handle handle, MojoWaitFlags flags, + virtual AsyncWaitID AsyncWait(const Handle& handle, MojoWaitFlags flags, AsyncWaitCallback* callback) OVERRIDE; virtual void CancelWait(AsyncWaitID async_wait_id) OVERRIDE; diff --git a/mojo/examples/hello_world_service/hello_world_service_impl.cc b/mojo/examples/hello_world_service/hello_world_service_impl.cc index d1060cb..63f536c 100644 --- a/mojo/examples/hello_world_service/hello_world_service_impl.cc +++ b/mojo/examples/hello_world_service/hello_world_service_impl.cc @@ -5,17 +5,18 @@ #include "mojo/examples/hello_world_service/hello_world_service_impl.h" #include <string> + #include "base/logging.h" namespace mojo { namespace examples { -HelloWorldServiceImpl::HelloWorldServiceImpl(mojo::Handle pipe) +HelloWorldServiceImpl::HelloWorldServiceImpl(const MessagePipeHandle& pipe) : client_(pipe) { client_.SetPeer(this); } -void HelloWorldServiceImpl::Greeting(const mojo::String* greeting) { +void HelloWorldServiceImpl::Greeting(const String* greeting) { LOG(INFO) << greeting->To<std::string>(); client_->DidReceiveGreeting(42); } diff --git a/mojo/examples/hello_world_service/hello_world_service_impl.h b/mojo/examples/hello_world_service/hello_world_service_impl.h index 6382617..5bc369f 100644 --- a/mojo/examples/hello_world_service/hello_world_service_impl.h +++ b/mojo/examples/hello_world_service/hello_world_service_impl.h @@ -13,12 +13,12 @@ namespace examples { class HelloWorldServiceImpl : public HelloWorldServiceStub { public: - explicit HelloWorldServiceImpl(mojo::Handle pipe); + explicit HelloWorldServiceImpl(const MessagePipeHandle& pipe); virtual ~HelloWorldServiceImpl(); - virtual void Greeting(const mojo::String* greeting) MOJO_OVERRIDE; + virtual void Greeting(const String* greeting) MOJO_OVERRIDE; private: - mojo::RemotePtr<HelloWorldClient> client_; + RemotePtr<HelloWorldClient> client_; }; } // examples diff --git a/mojo/examples/sample_app/hello_world_client_impl.cc b/mojo/examples/sample_app/hello_world_client_impl.cc index bda310e..606990f 100644 --- a/mojo/examples/sample_app/hello_world_client_impl.cc +++ b/mojo/examples/sample_app/hello_world_client_impl.cc @@ -11,7 +11,7 @@ namespace mojo { namespace examples { -HelloWorldClientImpl::HelloWorldClientImpl(mojo::Handle pipe) +HelloWorldClientImpl::HelloWorldClientImpl(const MessagePipeHandle& pipe) : service_(pipe) { service_.SetPeer(this); } diff --git a/mojo/examples/sample_app/hello_world_client_impl.h b/mojo/examples/sample_app/hello_world_client_impl.h index 4995406..9faa5d3 100644 --- a/mojo/examples/sample_app/hello_world_client_impl.h +++ b/mojo/examples/sample_app/hello_world_client_impl.h @@ -13,7 +13,7 @@ namespace examples { class HelloWorldClientImpl : public HelloWorldClientStub { public: - explicit HelloWorldClientImpl(mojo::Handle pipe); + explicit HelloWorldClientImpl(const MessagePipeHandle& pipe); virtual ~HelloWorldClientImpl(); virtual void DidReceiveGreeting(int32_t result) MOJO_OVERRIDE; @@ -23,7 +23,7 @@ class HelloWorldClientImpl : public HelloWorldClientStub { } private: - mojo::RemotePtr<HelloWorldService> service_; + RemotePtr<HelloWorldService> service_; }; } // examples diff --git a/mojo/examples/sample_app/sample_app.cc b/mojo/examples/sample_app/sample_app.cc index b071a4e..80f6d9b 100644 --- a/mojo/examples/sample_app/sample_app.cc +++ b/mojo/examples/sample_app/sample_app.cc @@ -25,12 +25,12 @@ namespace mojo { namespace examples { -void SayHello(mojo::Handle pipe) { +void SayHello(const MessagePipeHandle& pipe) { // Send message out. HelloWorldClientImpl client(pipe); - mojo::ScratchBuffer buf; + ScratchBuffer buf; const std::string kGreeting("hello, world!"); - mojo::String* greeting = mojo::String::NewCopyOf(&buf, kGreeting); + String* greeting = String::NewCopyOf(&buf, kGreeting); client.service()->Greeting(greeting); // Run loop to receieve Ack. The client will quit the loop. @@ -40,14 +40,13 @@ void SayHello(mojo::Handle pipe) { } // examples } // mojo -extern "C" SAMPLE_APP_EXPORT MojoResult CDECL MojoMain( - mojo::Handle pipe) { +extern "C" SAMPLE_APP_EXPORT MojoResult CDECL MojoMain(MojoHandle pipe) { base::MessageLoop loop; // Set the global bindings support. mojo::common::BindingsSupportImpl bindings_support; mojo::BindingsSupport::Set(&bindings_support); - mojo::examples::SayHello(pipe); + mojo::examples::SayHello(mojo::MessagePipeHandle(pipe)); mojo::BindingsSupport::Set(NULL); return MOJO_RESULT_OK; diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp index f5adca3..947a3fe 100644 --- a/mojo/mojo.gyp +++ b/mojo/mojo.gyp @@ -20,7 +20,6 @@ 'mojo_system_unittests', 'mojo_shell_lib', 'mojo_shell', - 'mojo_utility', 'mojo_js', 'sample_app', 'mojo_bindings', @@ -128,6 +127,7 @@ 'public/tests/bindings_remote_ptr_unittest.cc', 'public/tests/buffer_unittest.cc', 'public/tests/math_calculator.mojom', + 'public/tests/system_core_cpp_unittest.cc', 'public/tests/system_core_unittest.cc', ], 'includes': [ 'public/bindings/mojom_bindings_generator.gypi' ], @@ -231,7 +231,6 @@ '../url/url.gyp:url_lib', 'mojo_bindings', 'mojo_system', - 'mojo_utility', 'native_viewport', 'hello_world_service_impl', ], @@ -290,17 +289,6 @@ ], }, { - 'target_name': 'mojo_utility', - 'type': 'static_library', - 'dependencies': [ - 'mojo_system' - ], - 'sources': [ - 'public/utility/scoped_handle.cc', - 'public/utility/scoped_handle.h', - ], - }, - { 'target_name': 'mojo_js', 'type': 'shared_library', 'include_dirs': [ diff --git a/mojo/public/bindings/js/core.cc b/mojo/public/bindings/js/core.cc index f9fd0c2..8cc5ee1 100644 --- a/mojo/public/bindings/js/core.cc +++ b/mojo/public/bindings/js/core.cc @@ -20,17 +20,17 @@ namespace { void Close(const v8::FunctionCallbackInfo<v8::Value>& info) { gin::Arguments args(info); - mojo::Handle handle = mojo::kInvalidHandle; + mojo::Handle handle; if (!args.GetNext(&handle)) return args.ThrowError(); - args.Return(mojo::Close(handle)); + args.Return(mojo::CloseRaw(handle)); } void Wait(const v8::FunctionCallbackInfo<v8::Value>& info) { gin::Arguments args(info); - mojo::Handle handle = mojo::kInvalidHandle; + mojo::Handle handle; MojoWaitFlags flags = MOJO_WAIT_FLAG_NONE; MojoDeadline deadline = MOJO_DEADLINE_INDEFINITE; @@ -56,31 +56,26 @@ void WaitMany(const v8::FunctionCallbackInfo<v8::Value>& info) { return args.ThrowError(); } - if (handles.size() != flags.size()) - return args.ThrowTypeError("Arrays must have the same length."); - - args.Return(mojo::WaitMany(handles.data(), flags.data(), - static_cast<uint32_t>(handles.size()), deadline)); + args.Return(mojo::WaitMany(handles, flags, deadline)); } void CreateMessagePipe(const v8::FunctionCallbackInfo<v8::Value>& info) { gin::Arguments args(info); - mojo::Handle handle_0 = mojo::kInvalidHandle; - mojo::Handle handle_1 = mojo::kInvalidHandle; - MojoResult result = mojo::CreateMessagePipe(&handle_0, &handle_1); + mojo::ScopedMessagePipeHandle handle_0; + mojo::ScopedMessagePipeHandle handle_1; + mojo::CreateMessagePipe(&handle_0, &handle_1); gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(info.GetIsolate()); - dictionary.Set("result", result); - dictionary.Set("handle0", handle_0); - dictionary.Set("handle1", handle_1); + dictionary.Set("handle0", static_cast<mojo::Handle>(handle_0.release())); + dictionary.Set("handle1", static_cast<mojo::Handle>(handle_1.release())); args.Return(dictionary); } void WriteMessage(const v8::FunctionCallbackInfo<v8::Value>& info) { gin::Arguments args(info); - mojo::Handle handle = mojo::kInvalidHandle; + mojo::Handle handle; gin::ArrayBufferView buffer(args.isolate()); std::vector<mojo::Handle> handles; MojoWriteMessageFlags flags = MOJO_WRITE_MESSAGE_FLAG_NONE; @@ -92,17 +87,17 @@ void WriteMessage(const v8::FunctionCallbackInfo<v8::Value>& info) { return args.ThrowError(); } - args.Return(mojo::WriteMessage(handle, buffer.bytes(), - static_cast<uint32_t>(buffer.num_bytes()), - handles.data(), - static_cast<uint32_t>(handles.size()), - flags)); + args.Return(mojo::WriteMessageRaw( + MessagePipeHandle(handle.value()), buffer.bytes(), + static_cast<uint32_t>(buffer.num_bytes()), + handles.empty() ? NULL : reinterpret_cast<const MojoHandle*>(&handles[0]), + static_cast<uint32_t>(handles.size()), flags)); } void ReadMessage(const v8::FunctionCallbackInfo<v8::Value>& info) { gin::Arguments args(info); - mojo::Handle handle = mojo::kInvalidHandle; + mojo::Handle handle; gin::ArrayBufferView buffer(args.isolate()); uint32_t num_handles = 0; MojoReadMessageFlags flags = MOJO_READ_MESSAGE_FLAG_NONE; @@ -116,8 +111,10 @@ void ReadMessage(const v8::FunctionCallbackInfo<v8::Value>& info) { uint32_t num_bytes = static_cast<uint32_t>(buffer.num_bytes()); std::vector<mojo::Handle> handles(num_handles); - MojoResult result = mojo::ReadMessage(handle, buffer.bytes(), &num_bytes, - handles.data(), &num_handles, flags); + MojoResult result = mojo::ReadMessageRaw( + MessagePipeHandle(handle.value()), buffer.bytes(), &num_bytes, + handles.empty() ? NULL : reinterpret_cast<MojoHandle*>(&handles[0]), + &num_handles, flags); handles.resize(num_handles); // TODO(abarth): We should benchmark this codepath to make sure it's ok to @@ -156,8 +153,10 @@ v8::Local<v8::ObjectTemplate> Core::GetTemplate(v8::Isolate* isolate) { templ->Set(gin::StringToSymbol(isolate, "readMessage"), v8::FunctionTemplate::New(ReadMessage)); + // TODO(vtl): Change name of "kInvalidHandle", now that there's no such C++ + // constant? templ->Set(gin::StringToSymbol(isolate, "kInvalidHandle"), - gin::ConvertToV8(isolate, mojo::kInvalidHandle)); + gin::ConvertToV8(isolate, mojo::Handle())); templ->Set(gin::StringToSymbol(isolate, "RESULT_OK"), gin::ConvertToV8(isolate, MOJO_RESULT_OK)); diff --git a/mojo/public/bindings/js/handle.cc b/mojo/public/bindings/js/handle.cc index f52ef1c..3a601fe 100644 --- a/mojo/public/bindings/js/handle.cc +++ b/mojo/public/bindings/js/handle.cc @@ -7,13 +7,13 @@ namespace gin { v8::Handle<v8::Value> Converter<mojo::Handle>::ToV8(v8::Isolate* isolate, - mojo::Handle val) { - return Converter<MojoHandle>::ToV8(isolate, val.value); + const mojo::Handle& val) { + return Converter<MojoHandle>::ToV8(isolate, val.value()); } bool Converter<mojo::Handle>::FromV8(v8::Handle<v8::Value> val, mojo::Handle* out) { - return Converter<MojoHandle>::FromV8(val, &out->value); + return Converter<MojoHandle>::FromV8(val, out->mutable_value()); } } // namespace gin diff --git a/mojo/public/bindings/js/handle.h b/mojo/public/bindings/js/handle.h index 16a4e81..5e6af4b 100644 --- a/mojo/public/bindings/js/handle.h +++ b/mojo/public/bindings/js/handle.h @@ -6,14 +6,14 @@ #define MOJO_PUBLIC_BINDINGS_JS_HANDLE_H_ #include "gin/converter.h" -#include "mojo/public/system/core.h" +#include "mojo/public/system/core_cpp.h" namespace gin { template<> struct Converter<mojo::Handle> { static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, - mojo::Handle val); + const mojo::Handle& val); static bool FromV8(v8::Handle<v8::Value> val, mojo::Handle* out); }; diff --git a/mojo/public/bindings/lib/bindings_serialization.cc b/mojo/public/bindings/lib/bindings_serialization.cc index 6e64118..952eac1 100644 --- a/mojo/public/bindings/lib/bindings_serialization.cc +++ b/mojo/public/bindings/lib/bindings_serialization.cc @@ -46,13 +46,13 @@ bool ValidatePointer(const void* ptr, const Message& message) { void EncodeHandle(Handle* handle, std::vector<Handle>* handles) { handles->push_back(*handle); - handle->value = static_cast<MojoHandle>(handles->size() - 1); + handle->set_value(static_cast<MojoHandle>(handles->size() - 1)); } bool DecodeHandle(Handle* handle, const std::vector<Handle>& handles) { - if (handle->value >= handles.size()) + if (handle->value() >= handles.size()) return false; - *handle = handles[handle->value]; + *handle = handles[handle->value()]; return true; } diff --git a/mojo/public/bindings/lib/bindings_support.h b/mojo/public/bindings/lib/bindings_support.h index a1979f6..c275310 100644 --- a/mojo/public/bindings/lib/bindings_support.h +++ b/mojo/public/bindings/lib/bindings_support.h @@ -5,7 +5,7 @@ #ifndef MOJO_PUBLIC_BINDINGS_LIB_BINDINGS_SUPPORT_H_ #define MOJO_PUBLIC_BINDINGS_LIB_BINDINGS_SUPPORT_H_ -#include "mojo/public/system/core.h" +#include "mojo/public/system/core_cpp.h" namespace mojo { @@ -28,7 +28,7 @@ class BindingsSupport { // of MojoWait to the given AsyncWaitCallback on the current thread. Returns // an AsyncWaitID that can be used with CancelWait to stop waiting. This // identifier becomes invalid once the callback runs. - virtual AsyncWaitID AsyncWait(Handle handle, + virtual AsyncWaitID AsyncWait(const Handle& handle, MojoWaitFlags flags, AsyncWaitCallback* callback) = 0; diff --git a/mojo/public/bindings/lib/connector.cc b/mojo/public/bindings/lib/connector.cc index 5a8748d..ca0cede 100644 --- a/mojo/public/bindings/lib/connector.cc +++ b/mojo/public/bindings/lib/connector.cc @@ -13,7 +13,7 @@ namespace mojo { // ---------------------------------------------------------------------------- -Connector::Connector(Handle message_pipe) +Connector::Connector(const MessagePipeHandle& message_pipe) : message_pipe_(message_pipe), incoming_receiver_(NULL), error_(false) { @@ -73,12 +73,12 @@ void Connector::ReadMore() { MojoResult rv; uint32_t num_bytes = 0, num_handles = 0; - rv = ReadMessage(message_pipe_, - NULL, - &num_bytes, - NULL, - &num_handles, - MOJO_READ_MESSAGE_FLAG_NONE); + rv = ReadMessageRaw(message_pipe_, + NULL, + &num_bytes, + NULL, + &num_handles, + MOJO_READ_MESSAGE_FLAG_NONE); if (rv == MOJO_RESULT_NOT_FOUND) { WaitToReadMore(); break; @@ -92,12 +92,13 @@ void Connector::ReadMore() { message.data = static_cast<MessageData*>(malloc(num_bytes)); message.handles.resize(num_handles); - rv = ReadMessage(message_pipe_, - message.data, - &num_bytes, - message.handles.empty() ? NULL : &message.handles[0], - &num_handles, - MOJO_READ_MESSAGE_FLAG_NONE); + rv = ReadMessageRaw(message_pipe_, + message.data, + &num_bytes, + message.handles.empty() ? NULL : + reinterpret_cast<MojoHandle*>(&message.handles[0]), + &num_handles, + MOJO_READ_MESSAGE_FLAG_NONE); if (rv != MOJO_RESULT_OK) { error_ = true; break; @@ -121,17 +122,18 @@ void Connector::WriteMore() { } void Connector::WriteOne(Message* message, bool* wait_to_write) { - // TODO(darin): WriteMessage will eventually start generating an error that + // TODO(darin): WriteMessageRaw will eventually start generating an error that // it cannot accept more data. In that case, we'll need to wait on the pipe // to determine when we can try writing again. This flag will be set to true // in that case. *wait_to_write = false; - MojoResult rv = WriteMessage( + MojoResult rv = WriteMessageRaw( message_pipe_, message->data, message->data->header.num_bytes, - message->handles.empty() ? NULL : &message->handles[0], + message->handles.empty() ? NULL : + reinterpret_cast<const MojoHandle*>(&message->handles[0]), static_cast<uint32_t>(message->handles.size()), MOJO_WRITE_MESSAGE_FLAG_NONE); if (rv == MOJO_RESULT_OK) { diff --git a/mojo/public/bindings/lib/connector.h b/mojo/public/bindings/lib/connector.h index 4953e82..b78b55c 100644 --- a/mojo/public/bindings/lib/connector.h +++ b/mojo/public/bindings/lib/connector.h @@ -8,7 +8,7 @@ #include "mojo/public/bindings/lib/bindings_support.h" #include "mojo/public/bindings/lib/message.h" #include "mojo/public/bindings/lib/message_queue.h" -#include "mojo/public/system/core.h" +#include "mojo/public/system/core_cpp.h" namespace mojo { @@ -23,7 +23,7 @@ class Connector : public MessageReceiver { public: // The Connector does not take ownership of |message_pipe|. // TODO(darin): Perhaps it should take ownership. - explicit Connector(Handle message_pipe); + explicit Connector(const MessagePipeHandle& message_pipe); virtual ~Connector(); // Sets the receiver to handle messages read from the message pipe. The @@ -62,7 +62,7 @@ class Connector : public MessageReceiver { void WriteMore(); void WriteOne(Message* message, bool* wait_to_write); - Handle message_pipe_; + MessagePipeHandle message_pipe_; MessageReceiver* incoming_receiver_; MessageQueue write_queue_; diff --git a/mojo/public/bindings/lib/message.cc b/mojo/public/bindings/lib/message.cc index 4f6b6be..8b94832 100644 --- a/mojo/public/bindings/lib/message.cc +++ b/mojo/public/bindings/lib/message.cc @@ -16,7 +16,7 @@ Message::Message() Message::~Message() { free(data); - std::for_each(handles.begin(), handles.end(), Close); + std::for_each(handles.begin(), handles.end(), CloseRaw); } void Message::Swap(Message* other) { diff --git a/mojo/public/bindings/lib/message.h b/mojo/public/bindings/lib/message.h index bb9de25..1df1461 100644 --- a/mojo/public/bindings/lib/message.h +++ b/mojo/public/bindings/lib/message.h @@ -7,7 +7,7 @@ #include <vector> -#include "mojo/public/system/core.h" +#include "mojo/public/system/core_cpp.h" namespace mojo { @@ -38,6 +38,8 @@ class Message { void Swap(Message* other); MessageData* data; // Heap-allocated using malloc. + // TODO(vtl): Should these be ScopedHandles? How does that interact with + // encoding/decoding? std::vector<Handle> handles; private: diff --git a/mojo/public/bindings/lib/remote_ptr.h b/mojo/public/bindings/lib/remote_ptr.h index 2905992..91b292b 100644 --- a/mojo/public/bindings/lib/remote_ptr.h +++ b/mojo/public/bindings/lib/remote_ptr.h @@ -18,7 +18,7 @@ namespace mojo { // // class FooClientImpl : public FooClientStub { // public: -// explicit FooClientImpl(mojo::Handle message_pipe) +// explicit FooClientImpl(const mojo::MessagePipeHandle& message_pipe) // : foo_(message_pipe) { // foo_.SetPeer(this); // foo_.Ping(); @@ -34,7 +34,7 @@ namespace mojo { // // class FooImpl : public FooStub { // public: -// explicit FooImpl(mojo::Handle message_pipe) +// explicit FooImpl(const mojo::MessagePipeHandle& message_pipe) // : client_(message_pipe) { // client_.SetPeer(this); // } @@ -48,7 +48,7 @@ namespace mojo { template <typename S> class RemotePtr { public: - explicit RemotePtr(Handle message_pipe) + explicit RemotePtr(const MessagePipeHandle& message_pipe) : connector_(message_pipe), proxy_(&connector_) { } diff --git a/mojo/public/bindings/sample/mojom/sample_service.cc b/mojo/public/bindings/sample/mojom/sample_service.cc index ddaab1d..39beb04 100644 --- a/mojo/public/bindings/sample/mojom/sample_service.cc +++ b/mojo/public/bindings/sample/mojom/sample_service.cc @@ -31,7 +31,7 @@ class Service_Frobinate_Params { bool baz() const { return baz_; } mojo::Handle port() const { // NOTE: port is an optional field! - return _header_.num_fields >= 3 ? port_ : mojo::kInvalidHandle; + return _header_.num_fields >= 3 ? port_ : mojo::Handle(); } private: diff --git a/mojo/public/bindings/sample/sample_test.cc b/mojo/public/bindings/sample/sample_test.cc index 00a99ee..66dfda3 100644 --- a/mojo/public/bindings/sample/sample_test.cc +++ b/mojo/public/bindings/sample/sample_test.cc @@ -42,7 +42,7 @@ Foo* MakeFoo(mojo::ScratchBuffer* buf) { mojo::Array<mojo::Handle>* files = mojo::Array<mojo::Handle>::New(buf, 4); for (size_t i = 0; i < files->size(); ++i) - (*files)[i].value = static_cast<MojoHandle>(0xFFFF - i); + (*files)[i].set_value(static_cast<MojoHandle>(0xFFFF - i)); Foo* foo = Foo::New(buf); foo->set_name(name); @@ -97,7 +97,7 @@ void CheckFoo(const Foo* foo) { EXPECT_EQ(4u, foo->files()->size()); for (size_t i = 0; i < foo->files()->size(); ++i) EXPECT_EQ(static_cast<MojoHandle>(0xFFFF - i), - foo->files()->at(i).value) << i; + foo->files()->at(i).value()) << i; } @@ -123,7 +123,7 @@ static void Print(int depth, const char* name, uint8_t value) { static void Print(int depth, const char* name, mojo::Handle value) { PrintSpacer(depth); - printf("%s: 0x%x\n", name, value.value); + printf("%s: 0x%x\n", name, value.value()); } static void Print(int depth, const char* name, const mojo::String* str) { @@ -202,7 +202,7 @@ class ServiceImpl : public ServiceStub { // We mainly check that we're given the expected arguments. CheckFoo(foo); EXPECT_TRUE(baz); - EXPECT_EQ(static_cast<MojoHandle>(10), port.value); + EXPECT_EQ(static_cast<MojoHandle>(10), port.value()); // Also dump the Foo structure and all of its members. // TODO(vtl): Make it optional, so that the test spews less? @@ -249,7 +249,7 @@ TEST(BindingsSampleTest, Basic) { Foo* foo = MakeFoo(&buf); CheckFoo(foo); - mojo::Handle port = { 10 }; + mojo::Handle port(static_cast<MojoHandle>(10)); service->Frobinate(foo, true, port); } diff --git a/mojo/public/system/core.h b/mojo/public/system/core.h index 2ef42af..6292a6b 100644 --- a/mojo/public/system/core.h +++ b/mojo/public/system/core.h @@ -260,63 +260,4 @@ MOJO_SYSTEM_EXPORT MojoResult MojoReadMessage(MojoHandle handle, } // extern "C" #endif -// C++ wrapper functions ------------------------------------------------------- - -#ifdef __cplusplus - -namespace mojo { - -struct Handle { MojoHandle value; }; - -const Handle kInvalidHandle = { MOJO_HANDLE_INVALID }; - -// A |mojo::Handle| must take no extra space, since we'll treat arrays of them -// as if they were arrays of |MojoHandle|s. -MOJO_COMPILE_ASSERT(sizeof(Handle) == sizeof(MojoHandle), - bad_size_for_cplusplus_handle); - -inline MojoResult Close(Handle handle) { - return MojoClose(handle.value); -} - -inline MojoResult Wait(Handle handle, - MojoWaitFlags flags, - MojoDeadline deadline) { - return MojoWait(handle.value, flags, deadline); -} - -inline MojoResult WaitMany(const Handle* handles, - const MojoWaitFlags* flags, - uint32_t num_handles, - MojoDeadline deadline) { - return MojoWaitMany(&handles[0].value, flags, num_handles, deadline); -} - -inline MojoResult CreateMessagePipe(Handle* handle_0, Handle* handle_1) { - return MojoCreateMessagePipe(&handle_0->value, &handle_1->value); -} - -inline MojoResult WriteMessage(Handle handle, - const void* bytes, uint32_t num_bytes, - const Handle* handles, uint32_t num_handles, - MojoWriteMessageFlags flags) { - return MojoWriteMessage(handle.value, - bytes, num_bytes, - &handles[0].value, num_handles, - flags); -} - -inline MojoResult ReadMessage(Handle handle, - void* bytes, uint32_t* num_bytes, - Handle* handles, uint32_t* num_handles, - MojoReadMessageFlags flags) { - return MojoReadMessage(handle.value, - bytes, num_bytes, - &handles[0].value, num_handles, - flags); -} - -} // namespace mojo -#endif - #endif // MOJO_PUBLIC_SYSTEM_CORE_H_ diff --git a/mojo/public/system/core_cpp.h b/mojo/public/system/core_cpp.h new file mode 100644 index 0000000..b2c5075d --- /dev/null +++ b/mojo/public/system/core_cpp.h @@ -0,0 +1,213 @@ +// Copyright 2013 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 MOJO_PUBLIC_SYSTEM_CORE_CPP_H_ +#define MOJO_PUBLIC_SYSTEM_CORE_CPP_H_ + +#include <assert.h> + +#include <limits> + +#include "mojo/public/system/core.h" +#include "mojo/public/system/macros.h" +#include "mojo/public/system/system_export.h" + +namespace mojo { + +// ScopedHandleBase ------------------------------------------------------------ + +// Scoper for the actual handle types defined further below. It's move-only, +// like the C++11 |unique_ptr|. +template <class HandleType> +class ScopedHandleBase { + MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(ScopedHandleBase, RValue); + + public: + ScopedHandleBase() {} + ~ScopedHandleBase() { CloseIfNecessary(); } + + // Move-only constructor and operator=. + ScopedHandleBase(RValue other) : handle_(other.object->release()) {} + ScopedHandleBase& operator=(RValue other) { + handle_ = other.object->release(); + return *this; + } + + operator HandleType() const { return handle_; } + const HandleType& get() const { return handle_; } + + void swap(ScopedHandleBase& other) { + handle_.swap(other.handle_); + } + + HandleType release() MOJO_WARN_UNUSED_RESULT { + HandleType rv; + rv.swap(handle_); + return rv; + } + + void reset(HandleType handle = HandleType()) { + CloseIfNecessary(); + handle_ = handle; + } + + private: + void CloseIfNecessary() { + if (!handle_.is_valid()) + return; + MojoResult result MOJO_ALLOW_UNUSED = MojoClose(handle_.value()); + assert(result == MOJO_RESULT_OK); + } + + HandleType handle_; +}; + +// Handle ---------------------------------------------------------------------- + +const MojoHandle kInvalidHandleValue = MOJO_HANDLE_INVALID; + +// Wrapper base class for |MojoHandle|. +class Handle { + public: + Handle() : value_(MOJO_HANDLE_INVALID) {} + explicit Handle(MojoHandle value) : value_(value) {} + ~Handle() {} + + void swap(Handle& other) { + MojoHandle temp = value_; + value_ = other.value_; + other.value_ = temp; + } + + bool is_valid() const { + return value_ != MOJO_HANDLE_INVALID; + } + + MojoHandle value() const { return value_; } + MojoHandle* mutable_value() { return &value_; } + void set_value(MojoHandle value) { value_ = value; } + + private: + MojoHandle value_; + + // Copying and assignment allowed. +}; + +// Should have zero overhead. +MOJO_COMPILE_ASSERT(sizeof(Handle) == sizeof(MojoHandle), + bad_size_for_cpp_Handle); + +// The scoper should also impose no more overhead. +typedef ScopedHandleBase<Handle> ScopedHandle; +MOJO_COMPILE_ASSERT(sizeof(ScopedHandle) == sizeof(Handle), + bad_size_for_cpp_ScopedHandle); + +inline MojoResult Wait(const Handle& handle, + MojoWaitFlags flags, + MojoDeadline deadline) { + return MojoWait(handle.value(), flags, deadline); +} + +// |HandleVectorType| and |FlagsVectorType| should be similar enough to +// |std::vector<Handle>| and |std::vector<MojoWaitFlags>|, respectively: +// - They should have a (const) |size()| method that returns an unsigned type. +// - They must provide contiguous storage, with access via (const) reference to +// that storage provided by a (const) |operator[]()| (by reference). +template <class HandleVectorType, class FlagsVectorType> +inline MojoResult WaitMany(const HandleVectorType& handles, + const FlagsVectorType& flags, + MojoDeadline deadline) { + if (flags.size() != handles.size()) + return MOJO_RESULT_INVALID_ARGUMENT; + if (handles.size() > std::numeric_limits<uint32_t>::max()) + return MOJO_RESULT_OUT_OF_RANGE; + + if (handles.size() == 0) + return MojoWaitMany(NULL, NULL, 0, deadline); + + const Handle& first_handle = handles[0]; + const MojoWaitFlags& first_flag = flags[0]; + return MojoWaitMany(reinterpret_cast<const MojoHandle*>(&first_handle), + reinterpret_cast<const MojoWaitFlags*>(&first_flag), + static_cast<uint32_t>(handles.size()), + deadline); +} + +// |Close()| takes ownership of the handle, since it'll invalidate it. +// Note: There's nothing to do, since the argument will be destroyed when it +// goes out of scope. +template <class HandleType> +inline void Close(ScopedHandleBase<HandleType> /*handle*/) {} + +// Most users should typically use |Close()| (above) instead. +inline MojoResult CloseRaw(Handle handle) { + return MojoClose(handle.value()); +} + +// Strict weak ordering, so that |Handle|s can be used as keys in |std::map|s, +// etc. +inline bool operator<(const Handle& a, const Handle& b) { + return a.value() < b.value(); +} + +// MessagePipeHandle ----------------------------------------------------------- + +class MessagePipeHandle : public Handle { + public: + MessagePipeHandle() {} + explicit MessagePipeHandle(MojoHandle value) : Handle(value) {} + + // Copying and assignment allowed. +}; + +MOJO_COMPILE_ASSERT(sizeof(MessagePipeHandle) == sizeof(Handle), + bad_size_for_cpp_MessagePipeHandle); + +typedef ScopedHandleBase<MessagePipeHandle> ScopedMessagePipeHandle; +MOJO_COMPILE_ASSERT(sizeof(ScopedMessagePipeHandle) == + sizeof(MessagePipeHandle), + bad_size_for_cpp_ScopedMessagePipeHandle); + +// TODO(vtl): In C++11, we could instead return a pair of +// |ScopedHandleBase<MessagePipeHandle>|s. +inline void CreateMessagePipe(ScopedMessagePipeHandle* message_pipe_0, + ScopedMessagePipeHandle* message_pipe_1) { + assert(message_pipe_0); + assert(message_pipe_1); + MessagePipeHandle h_0; + MessagePipeHandle h_1; + MojoResult result MOJO_ALLOW_UNUSED = + MojoCreateMessagePipe(h_0.mutable_value(), h_1.mutable_value()); + assert(result == MOJO_RESULT_OK); + message_pipe_0->reset(h_0); + message_pipe_1->reset(h_1); +} + +// These "raw" versions fully expose the underlying API, but don't help with +// ownership of handles (especially when writing messages). +// TODO(vtl): Write "baked" versions. +inline MojoResult WriteMessageRaw( + MessagePipeHandle message_pipe, + const void* bytes, uint32_t num_bytes, + const MojoHandle* handles, uint32_t num_handles, + MojoWriteMessageFlags flags) { + return MojoWriteMessage(message_pipe.value(), + bytes, num_bytes, + handles, num_handles, + flags); +} + +inline MojoResult ReadMessageRaw(MessagePipeHandle message_pipe, + void* bytes, uint32_t* num_bytes, + MojoHandle* handles, uint32_t* num_handles, + MojoReadMessageFlags flags) { + return MojoReadMessage(message_pipe.value(), + bytes, num_bytes, + handles, num_handles, + flags); +} + +} // namespace mojo + +#endif // MOJO_PUBLIC_SYSTEM_CORE_CPP_H_ diff --git a/mojo/public/system/macros.h b/mojo/public/system/macros.h index ff73658..f3a6034 100644 --- a/mojo/public/system/macros.h +++ b/mojo/public/system/macros.h @@ -7,11 +7,28 @@ #include <stddef.h> +// Annotate a variable indicating it's okay if it's unused. +// Use like: +// int x MOJO_ALLOW_UNUSED = ...; +#if defined(__GNUC__) +#define MOJO_ALLOW_UNUSED __attribute__((unused)) +#else +#define MOJO_ALLOW_UNUSED +#endif + +// Annotate a function indicating that the caller must examine the return value. +// Use like: +// int foo() MOJO_WARN_UNUSED_RESULT; +#if defined(__GNUC__) +#define MOJO_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +#define MOJO_WARN_UNUSED_RESULT +#endif + #ifdef __cplusplus // Annotate a virtual method indicating it must be overriding a virtual method -// in the parent class. -// Use like: +// in the parent class. Use like: // virtual void foo() OVERRIDE; #if defined(_MSC_VER) || defined(__clang__) #define MOJO_OVERRIDE override @@ -30,7 +47,7 @@ namespace mojo { template <bool> struct CompileAssert {}; } #define MOJO_COMPILE_ASSERT(expr, msg) \ typedef ::mojo::CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] -// Use to calculate the number of elements in an array. +// Used to calculate the number of elements in an array. // (See |arraysize()| in Chromium's base/basictypes.h for more details.) namespace mojo { template <typename T, size_t N> @@ -42,6 +59,22 @@ char (&ArraySizeHelper(const T (&array)[N]))[N]; } // namespace mojo #define MOJO_ARRAYSIZE(array) (sizeof(::mojo::ArraySizeHelper(array))) +// Used to make a type move-only in C++03. See Chromium's base/move.h for more +// details. +#define MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(type, rvalue_type) \ + private: \ + struct rvalue_type { \ + explicit rvalue_type(type* object) : object(object) {} \ + type* object; \ + }; \ + type(type&); \ + void operator=(type&); \ + public: \ + operator rvalue_type() { return rvalue_type(this); } \ + type Pass() { return type(rvalue_type(this)); } \ + typedef void MoveOnlyTypeForCPP03; \ + private: + #endif // __cplusplus #endif // MOJO_PUBLIC_SYSTEM_MACROS_H_ diff --git a/mojo/public/tests/bindings_connector_unittest.cc b/mojo/public/tests/bindings_connector_unittest.cc index 654a027..6fe7750 100644 --- a/mojo/public/tests/bindings_connector_unittest.cc +++ b/mojo/public/tests/bindings_connector_unittest.cc @@ -39,9 +39,7 @@ class MessageAccumulator : public MessageReceiver { class BindingsConnectorTest : public testing::Test { public: - BindingsConnectorTest() - : handle0_(kInvalidHandle), - handle1_(kInvalidHandle) { + BindingsConnectorTest() { } virtual void SetUp() MOJO_OVERRIDE { @@ -49,8 +47,6 @@ class BindingsConnectorTest : public testing::Test { } virtual void TearDown() MOJO_OVERRIDE { - Close(handle0_); - Close(handle1_); } void AllocMessage(const char* text, Message* message) { @@ -67,8 +63,8 @@ class BindingsConnectorTest : public testing::Test { } protected: - Handle handle0_; - Handle handle1_; + ScopedMessagePipeHandle handle0_; + ScopedMessagePipeHandle handle1_; private: SimpleBindingsSupport bindings_support_; @@ -164,7 +160,7 @@ TEST_F(BindingsConnectorTest, WriteToClosedPipe) { Message message; AllocMessage(kText, &message); - Close(handle0_); // Close the handle before writing to it. + Close(handle0_.Pass()); // Close the handle before writing to it. bool ok = connector0.Accept(&message); EXPECT_FALSE(ok); @@ -182,9 +178,9 @@ TEST_F(BindingsConnectorTest, MessageWithHandles) { Message message; AllocMessage(kText, &message); - Handle handles[2]; + ScopedMessagePipeHandle handles[2]; CreateMessagePipe(&handles[0], &handles[1]); - message.handles.push_back(handles[0]); + message.handles.push_back(handles[0].release()); connector0.Accept(&message); @@ -208,7 +204,9 @@ TEST_F(BindingsConnectorTest, MessageWithHandles) { // Now send a message to the transferred handle and confirm it's sent through // to the orginal pipe. - Connector connector_received(message_received.handles[0]); + // TODO(vtl): Do we need a better way of "downcasting" the handle types? + Connector connector_received( + MessagePipeHandle(message_received.handles[0].value())); Connector connector_original(handles[1]); AllocMessage(kText, &message); diff --git a/mojo/public/tests/bindings_remote_ptr_unittest.cc b/mojo/public/tests/bindings_remote_ptr_unittest.cc index ea4cb3e..4005880 100644 --- a/mojo/public/tests/bindings_remote_ptr_unittest.cc +++ b/mojo/public/tests/bindings_remote_ptr_unittest.cc @@ -12,7 +12,7 @@ namespace test { class MathCalculatorImpl : public math::CalculatorStub { public: - explicit MathCalculatorImpl(Handle pipe) + explicit MathCalculatorImpl(const MessagePipeHandle& pipe) : ui_(pipe), total_(0.0) { ui_.SetPeer(this); @@ -39,7 +39,7 @@ class MathCalculatorImpl : public math::CalculatorStub { class MathCalculatorUIImpl : public math::CalculatorUIStub { public: - explicit MathCalculatorUIImpl(Handle pipe) + explicit MathCalculatorUIImpl(const MessagePipeHandle& pipe) : calculator_(pipe), output_(0.0) { calculator_.SetPeer(this); @@ -82,8 +82,6 @@ class BindingsRemotePtrTest : public testing::Test { } virtual ~BindingsRemotePtrTest() { - Close(pipe0_); - Close(pipe1_); } void PumpMessages() { @@ -91,8 +89,8 @@ class BindingsRemotePtrTest : public testing::Test { } protected: - Handle pipe0_; - Handle pipe1_; + ScopedMessagePipeHandle pipe0_; + ScopedMessagePipeHandle pipe1_; private: SimpleBindingsSupport bindings_support_; diff --git a/mojo/public/tests/simple_bindings_support.cc b/mojo/public/tests/simple_bindings_support.cc index d8b079c..59751bd 100644 --- a/mojo/public/tests/simple_bindings_support.cc +++ b/mojo/public/tests/simple_bindings_support.cc @@ -21,7 +21,7 @@ SimpleBindingsSupport::~SimpleBindingsSupport() { } BindingsSupport::AsyncWaitID SimpleBindingsSupport::AsyncWait( - Handle handle, + const Handle& handle, MojoWaitFlags flags, AsyncWaitCallback* callback) { Waiter* waiter = new Waiter(); @@ -77,7 +77,7 @@ void SimpleBindingsSupport::Process() { } } -bool SimpleBindingsSupport::IsReady(Handle handle, MojoWaitFlags flags, +bool SimpleBindingsSupport::IsReady(const Handle& handle, MojoWaitFlags flags, MojoResult* result) { *result = Wait(handle, flags, 0); return *result != MOJO_RESULT_DEADLINE_EXCEEDED; diff --git a/mojo/public/tests/simple_bindings_support.h b/mojo/public/tests/simple_bindings_support.h index 59131ba..8e870ab 100644 --- a/mojo/public/tests/simple_bindings_support.h +++ b/mojo/public/tests/simple_bindings_support.h @@ -17,7 +17,7 @@ class SimpleBindingsSupport : public BindingsSupport { SimpleBindingsSupport(); virtual ~SimpleBindingsSupport(); - virtual AsyncWaitID AsyncWait(Handle handle, + virtual AsyncWaitID AsyncWait(const Handle& handle, MojoWaitFlags flags, AsyncWaitCallback* callback) MOJO_OVERRIDE; virtual void CancelWait(AsyncWaitID async_wait_id) MOJO_OVERRIDE; @@ -28,7 +28,7 @@ class SimpleBindingsSupport : public BindingsSupport { void Process(); private: - bool IsReady(Handle handle, MojoWaitFlags flags, MojoResult* result); + bool IsReady(const Handle& handle, MojoWaitFlags flags, MojoResult* result); struct Waiter { Handle handle; diff --git a/mojo/public/tests/system_core_cpp_unittest.cc b/mojo/public/tests/system_core_cpp_unittest.cc new file mode 100644 index 0000000..92a6c98 --- /dev/null +++ b/mojo/public/tests/system_core_cpp_unittest.cc @@ -0,0 +1,274 @@ +// Copyright 2013 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. + +#include "mojo/public/system/core_cpp.h" + +#include <map> + +#include "mojo/public/system/macros.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace mojo { +namespace { + +TEST(CoreCppTest, Basic) { + // Basic |Handle| implementation: + { + EXPECT_EQ(MOJO_HANDLE_INVALID, kInvalidHandleValue); + + Handle h_0; + EXPECT_EQ(kInvalidHandleValue, h_0.value()); + EXPECT_EQ(kInvalidHandleValue, *h_0.mutable_value()); + EXPECT_FALSE(h_0.is_valid()); + + Handle h_1(static_cast<MojoHandle>(123)); + EXPECT_EQ(static_cast<MojoHandle>(123), h_1.value()); + EXPECT_EQ(static_cast<MojoHandle>(123), *h_1.mutable_value()); + EXPECT_TRUE(h_1.is_valid()); + *h_1.mutable_value() = static_cast<MojoHandle>(456); + EXPECT_EQ(static_cast<MojoHandle>(456), h_1.value()); + EXPECT_TRUE(h_1.is_valid()); + + h_1.swap(h_0); + EXPECT_EQ(static_cast<MojoHandle>(456), h_0.value()); + EXPECT_TRUE(h_0.is_valid()); + EXPECT_FALSE(h_1.is_valid()); + + h_1.set_value(static_cast<MojoHandle>(789)); + h_0.swap(h_1); + EXPECT_EQ(static_cast<MojoHandle>(789), h_0.value()); + EXPECT_TRUE(h_0.is_valid()); + EXPECT_EQ(static_cast<MojoHandle>(456), h_1.value()); + EXPECT_TRUE(h_1.is_valid()); + + // Make sure copy constructor works. + Handle h_2(h_0); + EXPECT_EQ(static_cast<MojoHandle>(789), h_2.value()); + // And assignment. + h_2 = h_1; + EXPECT_EQ(static_cast<MojoHandle>(456), h_2.value()); + + // Make sure that we can put |Handle|s into |std::map|s. + h_0 = Handle(static_cast<MojoHandle>(987)); + h_1 = Handle(static_cast<MojoHandle>(654)); + h_2 = Handle(static_cast<MojoHandle>(321)); + Handle h_3; + std::map<Handle, int> handle_to_int; + handle_to_int[h_0] = 0; + handle_to_int[h_1] = 1; + handle_to_int[h_2] = 2; + handle_to_int[h_3] = 3; + + EXPECT_EQ(4u, handle_to_int.size()); + EXPECT_FALSE(handle_to_int.find(h_0) == handle_to_int.end()); + EXPECT_EQ(0, handle_to_int[h_0]); + EXPECT_FALSE(handle_to_int.find(h_1) == handle_to_int.end()); + EXPECT_EQ(1, handle_to_int[h_1]); + EXPECT_FALSE(handle_to_int.find(h_2) == handle_to_int.end()); + EXPECT_EQ(2, handle_to_int[h_2]); + EXPECT_FALSE(handle_to_int.find(h_3) == handle_to_int.end()); + EXPECT_EQ(3, handle_to_int[h_3]); + EXPECT_TRUE(handle_to_int.find(Handle(static_cast<MojoHandle>(13579))) == + handle_to_int.end()); + + // TODO(vtl): With C++11, support |std::unordered_map|s, etc. (Or figure out + // how to support the variations of |hash_map|.) + } + + // |Handle|/|ScopedHandle| functions: + { + ScopedHandle h; + + EXPECT_EQ(kInvalidHandleValue, h.get().value()); + + // This should be a no-op. + Close(h.Pass()); + + // It should still be invalid. + EXPECT_EQ(kInvalidHandleValue, h.get().value()); + + EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + Wait(h, MOJO_WAIT_FLAG_EVERYTHING, 1000000)); + + std::vector<Handle> wh; + wh.push_back(h); + std::vector<MojoWaitFlags> wf; + wf.push_back(MOJO_WAIT_FLAG_EVERYTHING); + EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + WaitMany(wh, wf, MOJO_DEADLINE_INDEFINITE)); + } + + // |MessagePipeHandle|/|ScopedMessagePipeHandle| functions: + { + MessagePipeHandle h_invalid; + EXPECT_FALSE(h_invalid.is_valid()); + EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + WriteMessageRaw(h_invalid, + NULL, 0, + NULL, 0, + MOJO_WRITE_MESSAGE_FLAG_NONE)); + char buffer[10] = { 0 }; + EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + WriteMessageRaw(h_invalid, + buffer, sizeof(buffer), + NULL, 0, + MOJO_WRITE_MESSAGE_FLAG_NONE)); + EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + ReadMessageRaw(h_invalid, + NULL, NULL, + NULL, NULL, + MOJO_READ_MESSAGE_FLAG_NONE)); + uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); + EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + ReadMessageRaw(h_invalid, + buffer, &buffer_size, + NULL, NULL, + MOJO_READ_MESSAGE_FLAG_NONE)); + + // Basic tests of waiting and closing. + MojoHandle hv_0 = kInvalidHandleValue; + { + ScopedMessagePipeHandle h_0; + ScopedMessagePipeHandle h_1; + EXPECT_FALSE(h_0.get().is_valid()); + EXPECT_FALSE(h_1.get().is_valid()); + + CreateMessagePipe(&h_0, &h_1); + EXPECT_TRUE(h_0.get().is_valid()); + EXPECT_TRUE(h_1.get().is_valid()); + EXPECT_NE(h_0.get().value(), h_1.get().value()); + // Save the handle values, so we can check that things got closed + // correctly. + hv_0 = h_0.get().value(); + MojoHandle hv_1 = h_1.get().value(); + + EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, + Wait(h_0, MOJO_WAIT_FLAG_READABLE, 0)); + std::vector<Handle> wh; + wh.push_back(h_0); + wh.push_back(h_1); + std::vector<MojoWaitFlags> wf; + wf.push_back(MOJO_WAIT_FLAG_READABLE); + wf.push_back(MOJO_WAIT_FLAG_WRITABLE); + EXPECT_EQ(1, WaitMany(wh, wf, 1000)); + + // Test closing |h_1| explicitly. + Close(h_1.Pass()); + EXPECT_FALSE(h_1.get().is_valid()); + + // Make sure |h_1| is closed. + EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + MojoWait(hv_1, + MOJO_WAIT_FLAG_EVERYTHING, + MOJO_DEADLINE_INDEFINITE)); + + EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, + Wait(h_0, MOJO_WAIT_FLAG_READABLE, MOJO_DEADLINE_INDEFINITE)); + } + // |hv_0| should have been closed when |h_0| went out of scope, so this + // close should fail. + EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(hv_0)); + + // Actually test writing/reading messages. + { + ScopedMessagePipeHandle h_0; + ScopedMessagePipeHandle h_1; + CreateMessagePipe(&h_0, &h_1); + + const char kHello[] = "hello"; + const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello)); + EXPECT_EQ(MOJO_RESULT_OK, + WriteMessageRaw(h_0, + kHello, kHelloSize, + NULL, 0, + MOJO_WRITE_MESSAGE_FLAG_NONE)); + EXPECT_EQ(MOJO_RESULT_OK, + Wait(h_1, MOJO_WAIT_FLAG_READABLE, MOJO_DEADLINE_INDEFINITE)); + char buffer[10] = { 0 }; + uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); + EXPECT_EQ(MOJO_RESULT_OK, + ReadMessageRaw(h_1, + buffer, &buffer_size, + NULL, NULL, + MOJO_READ_MESSAGE_FLAG_NONE)); + EXPECT_EQ(kHelloSize, buffer_size); + EXPECT_STREQ(kHello, buffer); + + // Send a handle over the previously-establish |MessagePipe|. + ScopedMessagePipeHandle h_2; + ScopedMessagePipeHandle h_3; + CreateMessagePipe(&h_2, &h_3); + + // Write a message to |h_2|, before we send |h_3|. + const char kWorld[] = "world!"; + const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld)); + EXPECT_EQ(MOJO_RESULT_OK, + WriteMessageRaw(h_2, + kWorld, kWorldSize, + NULL, 0, + MOJO_WRITE_MESSAGE_FLAG_NONE)); + + // Send |h_3| over |h_1| to |h_0|. + MojoHandle handles[5]; + handles[0] = h_3.release().value(); + EXPECT_NE(kInvalidHandleValue, handles[0]); + EXPECT_FALSE(h_3.get().is_valid()); + uint32_t handles_count = 1; + EXPECT_EQ(MOJO_RESULT_OK, + WriteMessageRaw(h_1, + kHello, kHelloSize, + handles, handles_count, + MOJO_WRITE_MESSAGE_FLAG_NONE)); + // |handles[0]| should actually be invalid now. + EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handles[0])); + + // TODO(vtl): Bug (in code): if the scope ended here, the test crashes. + + // Read "hello" and the sent handle. + EXPECT_EQ(MOJO_RESULT_OK, + Wait(h_0, MOJO_WAIT_FLAG_READABLE, MOJO_DEADLINE_INDEFINITE)); + memset(buffer, 0, sizeof(buffer)); + buffer_size = static_cast<uint32_t>(sizeof(buffer)); + for (size_t i = 0; i < MOJO_ARRAYSIZE(handles); i++) + handles[i] = kInvalidHandleValue; + handles_count = static_cast<uint32_t>(MOJO_ARRAYSIZE(handles)); + EXPECT_EQ(MOJO_RESULT_OK, + ReadMessageRaw(h_0, + buffer, &buffer_size, + handles, &handles_count, + MOJO_READ_MESSAGE_FLAG_NONE)); + EXPECT_EQ(kHelloSize, buffer_size); + EXPECT_STREQ(kHello, buffer); + EXPECT_EQ(1u, handles_count); + EXPECT_NE(kInvalidHandleValue, handles[0]); + + // Read from the sent/received handle. + h_3.reset(MessagePipeHandle(handles[0])); + // Save |handles[0]| to check that it gets properly closed. + hv_0 = handles[0]; + EXPECT_EQ(MOJO_RESULT_OK, + Wait(h_3, MOJO_WAIT_FLAG_READABLE, MOJO_DEADLINE_INDEFINITE)); + memset(buffer, 0, sizeof(buffer)); + buffer_size = static_cast<uint32_t>(sizeof(buffer)); + for (size_t i = 0; i < MOJO_ARRAYSIZE(handles); i++) + handles[i] = kInvalidHandleValue; + handles_count = static_cast<uint32_t>(MOJO_ARRAYSIZE(handles)); + EXPECT_EQ(MOJO_RESULT_OK, + ReadMessageRaw(h_3, + buffer, &buffer_size, + handles, &handles_count, + MOJO_READ_MESSAGE_FLAG_NONE)); + EXPECT_EQ(kWorldSize, buffer_size); + EXPECT_STREQ(kWorld, buffer); + EXPECT_EQ(0u, handles_count); + } + EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(hv_0)); + } + + // TODO(vtl): Test |CloseRaw()|. + // TODO(vtl): Test |reset()| more thoroughly? +} + +} // namespace +} // namespace mojo diff --git a/mojo/public/tests/system_core_perftest.cc b/mojo/public/tests/system_core_perftest.cc index c6a0508..170c3d6 100644 --- a/mojo/public/tests/system_core_perftest.cc +++ b/mojo/public/tests/system_core_perftest.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// This tests the performance of the C API. + #include "mojo/public/system/core.h" #include "base/basictypes.h" @@ -10,7 +12,6 @@ #include "mojo/public/tests/test_support.h" #include "testing/gtest/include/gtest/gtest.h" -namespace mojo { namespace { class SystemPerftest : public testing::Test { @@ -23,41 +24,41 @@ class SystemPerftest : public testing::Test { void MessagePipe_CreateAndClose() { MojoResult result; - result = CreateMessagePipe(&h_0_, &h_1_); + result = MojoCreateMessagePipe(&h_0_, &h_1_); DCHECK_EQ(result, MOJO_RESULT_OK); - result = Close(h_0_); + result = MojoClose(h_0_); DCHECK_EQ(result, MOJO_RESULT_OK); - result = Close(h_1_); + result = MojoClose(h_1_); DCHECK_EQ(result, MOJO_RESULT_OK); } void MessagePipe_WriteAndRead(void* buffer, uint32_t bytes) { MojoResult result; - result = WriteMessage(h_0_, - buffer, bytes, - NULL, 0, - MOJO_WRITE_MESSAGE_FLAG_NONE); + result = MojoWriteMessage(h_0_, + buffer, bytes, + NULL, 0, + MOJO_WRITE_MESSAGE_FLAG_NONE); DCHECK_EQ(result, MOJO_RESULT_OK); uint32_t read_bytes = bytes; - result = ReadMessage(h_1_, - buffer, &read_bytes, - NULL, NULL, - MOJO_READ_MESSAGE_FLAG_NONE); + result = MojoReadMessage(h_1_, + buffer, &read_bytes, + NULL, NULL, + MOJO_READ_MESSAGE_FLAG_NONE); DCHECK_EQ(result, MOJO_RESULT_OK); } void MessagePipe_EmptyRead() { MojoResult result; - result = ReadMessage(h_0_, - NULL, NULL, - NULL, NULL, - MOJO_READ_MESSAGE_FLAG_MAY_DISCARD); + result = MojoReadMessage(h_0_, + NULL, NULL, + NULL, NULL, + MOJO_READ_MESSAGE_FLAG_MAY_DISCARD); DCHECK_EQ(result, MOJO_RESULT_NOT_FOUND); } protected: - Handle h_0_; - Handle h_1_; + MojoHandle h_0_; + MojoHandle h_1_; private: DISALLOW_COPY_AND_ASSIGN(SystemPerftest); @@ -65,55 +66,54 @@ class SystemPerftest : public testing::Test { // A no-op test so we can compare performance. TEST_F(SystemPerftest, NoOp) { - test::IterateAndReportPerf( + mojo::test::IterateAndReportPerf( "NoOp", base::Bind(&SystemPerftest::NoOp, base::Unretained(this))); } TEST_F(SystemPerftest, MessagePipe_CreateAndClose) { - test::IterateAndReportPerf( + mojo::test::IterateAndReportPerf( "MessagePipe_CreateAndClose", base::Bind(&SystemPerftest::MessagePipe_CreateAndClose, base::Unretained(this))); } TEST_F(SystemPerftest, MessagePipe_WriteAndRead) { - CHECK_EQ(CreateMessagePipe(&h_0_, &h_1_), MOJO_RESULT_OK); + CHECK_EQ(MojoCreateMessagePipe(&h_0_, &h_1_), MOJO_RESULT_OK); char buffer[10000] = { 0 }; - test::IterateAndReportPerf( + mojo::test::IterateAndReportPerf( "MessagePipe_WriteAndRead_10bytes", base::Bind(&SystemPerftest::MessagePipe_WriteAndRead, base::Unretained(this), static_cast<void*>(buffer), static_cast<uint32_t>(10))); - test::IterateAndReportPerf( + mojo::test::IterateAndReportPerf( "MessagePipe_WriteAndRead_100bytes", base::Bind(&SystemPerftest::MessagePipe_WriteAndRead, base::Unretained(this), static_cast<void*>(buffer), static_cast<uint32_t>(100))); - test::IterateAndReportPerf( + mojo::test::IterateAndReportPerf( "MessagePipe_WriteAndRead_1000bytes", base::Bind(&SystemPerftest::MessagePipe_WriteAndRead, base::Unretained(this), static_cast<void*>(buffer), static_cast<uint32_t>(1000))); - test::IterateAndReportPerf( + mojo::test::IterateAndReportPerf( "MessagePipe_WriteAndRead_10000bytes", base::Bind(&SystemPerftest::MessagePipe_WriteAndRead, base::Unretained(this), static_cast<void*>(buffer), static_cast<uint32_t>(10000))); - CHECK_EQ(Close(h_0_), MOJO_RESULT_OK); - CHECK_EQ(Close(h_1_), MOJO_RESULT_OK); + CHECK_EQ(MojoClose(h_0_), MOJO_RESULT_OK); + CHECK_EQ(MojoClose(h_1_), MOJO_RESULT_OK); } TEST_F(SystemPerftest, MessagePipe_EmptyRead) { - CHECK_EQ(CreateMessagePipe(&h_0_, &h_1_), MOJO_RESULT_OK); - test::IterateAndReportPerf( + CHECK_EQ(MojoCreateMessagePipe(&h_0_, &h_1_), MOJO_RESULT_OK); + mojo::test::IterateAndReportPerf( "MessagePipe_EmptyRead", base::Bind(&SystemPerftest::MessagePipe_EmptyRead, base::Unretained(this))); - CHECK_EQ(Close(h_0_), MOJO_RESULT_OK); - CHECK_EQ(Close(h_1_), MOJO_RESULT_OK); + CHECK_EQ(MojoClose(h_0_), MOJO_RESULT_OK); + CHECK_EQ(MojoClose(h_1_), MOJO_RESULT_OK); } } // namespace -} // namespace mojo diff --git a/mojo/public/tests/system_core_unittest.cc b/mojo/public/tests/system_core_unittest.cc index 8c7d1e5..9626058 100644 --- a/mojo/public/tests/system_core_unittest.cc +++ b/mojo/public/tests/system_core_unittest.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// This file tests the C API. + #include "mojo/public/system/core.h" #include <string.h> @@ -12,87 +14,89 @@ namespace mojo { namespace { TEST(SystemTest, Basic) { - Handle h_0; + MojoHandle h_0; MojoWaitFlags wf; char buffer[10] = { 0 }; uint32_t buffer_size; - // The only handle that's guaranteed to be invalid is |kInvalidHandle|. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, Close(kInvalidHandle)); + // The only handle that's guaranteed to be invalid is |MOJO_HANDLE_INVALID|. + EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(MOJO_HANDLE_INVALID)); EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - Wait(kInvalidHandle, MOJO_WAIT_FLAG_EVERYTHING, 1000000)); - h_0 = kInvalidHandle; + MojoWait(MOJO_HANDLE_INVALID, MOJO_WAIT_FLAG_EVERYTHING, 1000000)); + h_0 = MOJO_HANDLE_INVALID; wf = MOJO_WAIT_FLAG_EVERYTHING; EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - WaitMany(&h_0, &wf, 1, MOJO_DEADLINE_INDEFINITE)); + MojoWaitMany(&h_0, &wf, 1, MOJO_DEADLINE_INDEFINITE)); EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - WriteMessage(h_0, - buffer, 3, - NULL, 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); + MojoWriteMessage(h_0, + buffer, 3, + NULL, 0, + MOJO_WRITE_MESSAGE_FLAG_NONE)); buffer_size = static_cast<uint32_t>(sizeof(buffer)); EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - ReadMessage(h_0, - buffer, &buffer_size, - NULL, NULL, - MOJO_READ_MESSAGE_FLAG_NONE)); + MojoReadMessage(h_0, + buffer, &buffer_size, + NULL, NULL, + MOJO_READ_MESSAGE_FLAG_NONE)); - Handle h_1; - EXPECT_EQ(MOJO_RESULT_OK, CreateMessagePipe(&h_0, &h_1)); + MojoHandle h_1; + EXPECT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(&h_0, &h_1)); // Shouldn't be readable. EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, - Wait(h_0, MOJO_WAIT_FLAG_READABLE, 0)); + MojoWait(h_0, MOJO_WAIT_FLAG_READABLE, 0)); // Should be writable. EXPECT_EQ(MOJO_RESULT_OK, - Wait(h_0, MOJO_WAIT_FLAG_WRITABLE, 0)); + MojoWait(h_0, MOJO_WAIT_FLAG_WRITABLE, 0)); // Try to read. EXPECT_EQ(MOJO_RESULT_NOT_FOUND, - ReadMessage(h_0, - buffer, &buffer_size, - NULL, NULL, - MOJO_READ_MESSAGE_FLAG_NONE)); + MojoReadMessage(h_0, + buffer, &buffer_size, + NULL, NULL, + MOJO_READ_MESSAGE_FLAG_NONE)); // Write to |h_1|. static const char hello[] = "hello"; memcpy(buffer, hello, sizeof(hello)); buffer_size = static_cast<uint32_t>(sizeof(hello)); EXPECT_EQ(MOJO_RESULT_OK, - WriteMessage(h_1, - hello, buffer_size, - NULL, 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); + MojoWriteMessage(h_1, + hello, buffer_size, + NULL, 0, + MOJO_WRITE_MESSAGE_FLAG_NONE)); // |h_0| should be readable. wf = MOJO_WAIT_FLAG_READABLE; EXPECT_EQ(MOJO_RESULT_OK, - WaitMany(&h_0, &wf, 1, MOJO_DEADLINE_INDEFINITE)); + MojoWaitMany(&h_0, &wf, 1, MOJO_DEADLINE_INDEFINITE)); // Read from |h_0|. memset(buffer, 0, sizeof(buffer)); buffer_size = static_cast<uint32_t>(sizeof(buffer)); EXPECT_EQ(MOJO_RESULT_OK, - ReadMessage(h_0, - buffer, &buffer_size, - NULL, NULL, - MOJO_READ_MESSAGE_FLAG_NONE)); + MojoReadMessage(h_0, + buffer, &buffer_size, + NULL, NULL, + MOJO_READ_MESSAGE_FLAG_NONE)); EXPECT_EQ(static_cast<uint32_t>(sizeof(hello)), buffer_size); EXPECT_EQ(0, memcmp(hello, buffer, sizeof(hello))); // |h_0| should no longer be readable. EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, - Wait(h_0, MOJO_WAIT_FLAG_READABLE, 10)); + MojoWait(h_0, MOJO_WAIT_FLAG_READABLE, 10)); // Close |h_0|. - EXPECT_EQ(MOJO_RESULT_OK, Close(h_0)); + EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h_0)); // |h_1| should no longer be readable or writable. EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, - Wait(h_1, MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE, 1000)); + MojoWait(h_1, + MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE, + 1000)); - EXPECT_EQ(MOJO_RESULT_OK, Close(h_1)); + EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h_1)); } // TODO(vtl): Add multi-threaded tests. diff --git a/mojo/public/utility/scoped_handle.cc b/mojo/public/utility/scoped_handle.cc deleted file mode 100644 index cba4b8a..0000000 --- a/mojo/public/utility/scoped_handle.cc +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2013 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. - -#include "mojo/public/utility/scoped_handle.h" - -namespace mojo { - -ScopedHandle::ScopedHandle(Handle handle) : handle_(handle) { -} - -ScopedHandle::~ScopedHandle() { - if (handle_.value == kInvalidHandle.value) - return; - Close(handle_); - Release(); -} - -Handle ScopedHandle::Release() { - Handle temp = handle_; - handle_ = kInvalidHandle; - return temp; -} - -} // namespace mojo diff --git a/mojo/public/utility/scoped_handle.h b/mojo/public/utility/scoped_handle.h deleted file mode 100644 index e153baa..0000000 --- a/mojo/public/utility/scoped_handle.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2013 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 MOJO_PUBLIC_UTILITY_SCOPED_HANDLE_H_ -#define MOJO_PUBLIC_UTILITY_SCOPED_HANDLE_H_ - -#include "mojo/public/system/core.h" - -namespace mojo { - -// Closes handle_ when deleted. -// This probably wants tons of improvements, but those can be made as needed. -class ScopedHandle { - public: - ScopedHandle(Handle handle); - ~ScopedHandle(); - Handle get() const { return handle_; } - Handle Release(); - - private: - Handle handle_; -}; - -} // namespace mojo - -#endif // MOJO_PUBLIC_SYSTEM_SCOPED_HANDLE_H_ diff --git a/mojo/services/native_viewport/native_viewport_controller.cc b/mojo/services/native_viewport/native_viewport_controller.cc index ee35084..a4b4f3e 100644 --- a/mojo/services/native_viewport/native_viewport_controller.cc +++ b/mojo/services/native_viewport/native_viewport_controller.cc @@ -18,7 +18,7 @@ namespace mojo { namespace services { NativeViewportController::NativeViewportController( - shell::Context* context, Handle pipe) + shell::Context* context, const MessagePipeHandle& pipe) : pipe_(pipe) { native_viewport_ = NativeViewport::Create(context, this); native_viewport_->Init(); @@ -73,8 +73,9 @@ void NativeViewportController::OnDestroyed() { void NativeViewportController::SendString(const std::string& string) { DCHECK_LT(string.size() + 1, std::numeric_limits<uint32_t>::max()); - WriteMessage(pipe_, string.c_str(), static_cast<uint32_t>(string.size() + 1), - NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE); + WriteMessageRaw(pipe_, string.c_str(), + static_cast<uint32_t>(string.size() + 1), + NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE); } } // namespace services diff --git a/mojo/services/native_viewport/native_viewport_controller.h b/mojo/services/native_viewport/native_viewport_controller.h index c65c02c..e837d15 100644 --- a/mojo/services/native_viewport/native_viewport_controller.h +++ b/mojo/services/native_viewport/native_viewport_controller.h @@ -7,7 +7,7 @@ #include <string> -#include "mojo/public/system/core.h" +#include "mojo/public/system/core_cpp.h" #include "mojo/services/native_viewport/native_viewport.h" namespace gpu { @@ -23,7 +23,7 @@ class NativeViewportController : public services::NativeViewportDelegate { // mojo_shell and the loaded app. This should really be hidden // behind the bindings layer, when that comes up. NativeViewportController(shell::Context* context, - Handle pipe); + const MessagePipeHandle& pipe); virtual ~NativeViewportController(); void Close(); @@ -40,7 +40,7 @@ class NativeViewportController : public services::NativeViewportDelegate { void SendString(const std::string& string); - Handle pipe_; + MessagePipeHandle pipe_; scoped_ptr<NativeViewport> native_viewport_; scoped_ptr<gpu::GLInProcessContext> gl_context_; diff --git a/mojo/shell/app_container.cc b/mojo/shell/app_container.cc index 6699b1a..4630ce5 100644 --- a/mojo/shell/app_container.cc +++ b/mojo/shell/app_container.cc @@ -14,18 +14,16 @@ #include "base/thread_task_runner_handle.h" #include "base/threading/thread.h" #include "mojo/public/system/core.h" -#include "mojo/public/utility/scoped_handle.h" #include "mojo/services/native_viewport/native_viewport_controller.h" #include "mojo/shell/context.h" -typedef MojoResult (*MojoMainFunction)(mojo::Handle pipe); +typedef MojoResult (*MojoMainFunction)(MojoHandle pipe); namespace mojo { namespace shell { AppContainer::AppContainer(Context* context) : context_(context), - app_handle_raw_(mojo::kInvalidHandle), weak_factory_(this) { } @@ -38,14 +36,10 @@ void AppContainer::Load(const GURL& app_url) { void AppContainer::DidCompleteLoad(const GURL& app_url, const base::FilePath& app_path) { - Handle shell_handle; - MojoResult result = CreateMessagePipe(&shell_handle, &app_handle_raw_); - if (result < MOJO_RESULT_OK) { - // Failure.. - } + CreateMessagePipe(&shell_handle_, &app_handle_); hello_world_service_.reset( - new examples::HelloWorldServiceImpl(shell_handle)); + new examples::HelloWorldServiceImpl(shell_handle_)); // Launch the app on its own thread. // TODO(beng): Create a unique thread name. @@ -64,8 +58,6 @@ void AppContainer::DidCompleteLoad(const GURL& app_url, void AppContainer::Run() { base::ScopedClosureRunner app_deleter( base::Bind(base::IgnoreResult(&base::DeleteFile), app_path_, false)); - ScopedHandle app_handle(app_handle_raw_); - base::ScopedNativeLibrary app_library( base::LoadNativeLibrary(app_path_, NULL)); if (!app_library.is_valid()) { @@ -80,7 +72,8 @@ void AppContainer::Run() { return; } - MojoResult result = main_function(app_handle.get()); + // |MojoMain()| takes ownership of the app handle. + MojoResult result = main_function(app_handle_.release().value()); if (result < MOJO_RESULT_OK) { LOG(ERROR) << "MojoMain returned an error: " << result; return; diff --git a/mojo/shell/app_container.h b/mojo/shell/app_container.h index 09231d7..7963646 100644 --- a/mojo/shell/app_container.h +++ b/mojo/shell/app_container.h @@ -10,7 +10,7 @@ #include "base/memory/weak_ptr.h" #include "base/threading/simple_thread.h" #include "mojo/examples/hello_world_service/hello_world_service_impl.h" -#include "mojo/public/system/core.h" +#include "mojo/public/system/core_cpp.h" #include "mojo/shell/loader.h" namespace base { @@ -48,7 +48,8 @@ class AppContainer Context* context_; base::FilePath app_path_; - Handle app_handle_raw_; + ScopedMessagePipeHandle shell_handle_; + ScopedMessagePipeHandle app_handle_; base::Closure ack_closure_; scoped_ptr<Loader::Job> request_; scoped_ptr<base::DelegateSimpleThread> thread_; |