NaCl: create a separate namespace for Mojo handles. BUG=401761 R=viettrungluu@chromium.org Review URL: https://codereview.chromium.org/1052723003
diff --git a/mojo/edk/embedder/BUILD.gn b/mojo/edk/embedder/BUILD.gn index 9650209..2953982 100644 --- a/mojo/edk/embedder/BUILD.gn +++ b/mojo/edk/embedder/BUILD.gn
@@ -16,6 +16,7 @@ "embedder.h", "embedder_internal.h", "entrypoints.cc", + "system_impl_private_entrypoints.cc", # Test-only code: # TODO(vtl): It's a little unfortunate that these end up in the same @@ -37,6 +38,8 @@ ":platform", ] + mojo_sdk_deps = [ "mojo/public/platform/native:system_impl_private_api" ] + mojo_sdk_public_deps = [ "mojo/public/cpp/system" ] deps = [
diff --git a/mojo/edk/embedder/system_impl_private_entrypoints.cc b/mojo/edk/embedder/system_impl_private_entrypoints.cc new file mode 100644 index 0000000..475ffa7 --- /dev/null +++ b/mojo/edk/embedder/system_impl_private_entrypoints.cc
@@ -0,0 +1,260 @@ +// Copyright 2015 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/edk/embedder/embedder_internal.h" +#include "mojo/edk/system/core.h" +#include "mojo/edk/system/dispatcher.h" +#include "mojo/public/c/system/buffer.h" +#include "mojo/public/c/system/data_pipe.h" +#include "mojo/public/c/system/functions.h" +#include "mojo/public/c/system/message_pipe.h" +#include "mojo/public/platform/native/system_impl_private.h" + +using mojo::embedder::internal::g_core; +using mojo::system::Core; +using mojo::system::Dispatcher; +using mojo::system::MakeUserPointer; + +// Definitions of the system functions, but with an explicit parameter for the +// core object rather than using the default singleton. Also includes functions +// for manipulating core objects. +extern "C" { + +MojoSystemImpl MojoSystemImplGetDefaultImpl() { + return static_cast<MojoSystemImpl>(g_core); +} + +MojoSystemImpl MojoSystemImplCreateImpl() { + Core* created_core = new Core(g_core->platform_support()); + return static_cast<MojoSystemImpl>(created_core); +} + +MojoResult MojoSystemImplTransferHandle(MojoSystemImpl from_system, + MojoHandle handle, + MojoSystemImpl to_system, + MojoHandle* result_handle) { + Core* from_core = static_cast<Core*>(from_system); + if (from_core == nullptr) + return MOJO_RESULT_INVALID_ARGUMENT; + + if (handle == MOJO_HANDLE_INVALID) + return MOJO_RESULT_INVALID_ARGUMENT; + + Core* to_core = static_cast<Core*>(to_system); + if (to_core == nullptr) + return MOJO_RESULT_INVALID_ARGUMENT; + + if (result_handle == nullptr) + return MOJO_RESULT_INVALID_ARGUMENT; + + scoped_refptr<Dispatcher> d; + MojoResult result = from_core->GetAndRemoveDispatcher(handle, &d); + if (result != MOJO_RESULT_OK) + return result; + + MojoHandle created_handle = to_core->AddDispatcher(d); + if (created_handle == MOJO_HANDLE_INVALID) { + // The handle has been lost, unfortunately. There's no guarentee we can put + // it back where it came from, or get the original ID back. Holding locks + // for multiple cores risks deadlock, so that isn't a solution. This case + // should not happen for reasonable uses of this API, however. + LOG(ERROR) << "Could not transfer handle"; + d->Close(); + return MOJO_RESULT_RESOURCE_EXHAUSTED; + } + + MakeUserPointer(result_handle).Put(created_handle); + return MOJO_RESULT_OK; +} + +MojoTimeTicks MojoSystemImplGetTimeTicksNow(MojoSystemImpl system) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->GetTimeTicksNow(); +} + +MojoResult MojoSystemImplClose(MojoSystemImpl system, MojoHandle handle) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->Close(handle); +} + +MojoResult MojoSystemImplWait(MojoSystemImpl system, + MojoHandle handle, + MojoHandleSignals signals, + MojoDeadline deadline, + MojoHandleSignalsState* signals_state) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->Wait(handle, signals, deadline, MakeUserPointer(signals_state)); +} + +MojoResult MojoSystemImplWaitMany(MojoSystemImpl system, + const MojoHandle* handles, + const MojoHandleSignals* signals, + uint32_t num_handles, + MojoDeadline deadline, + uint32_t* result_index, + MojoHandleSignalsState* signals_states) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->WaitMany(MakeUserPointer(handles), MakeUserPointer(signals), + num_handles, deadline, MakeUserPointer(result_index), + MakeUserPointer(signals_states)); +} + +MojoResult MojoSystemImplCreateMessagePipe( + MojoSystemImpl system, + const MojoCreateMessagePipeOptions* options, + MojoHandle* message_pipe_handle0, + MojoHandle* message_pipe_handle1) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->CreateMessagePipe(MakeUserPointer(options), + MakeUserPointer(message_pipe_handle0), + MakeUserPointer(message_pipe_handle1)); +} + +MojoResult MojoSystemImplWriteMessage(MojoSystemImpl system, + MojoHandle message_pipe_handle, + const void* bytes, + uint32_t num_bytes, + const MojoHandle* handles, + uint32_t num_handles, + MojoWriteMessageFlags flags) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->WriteMessage(message_pipe_handle, MakeUserPointer(bytes), + num_bytes, MakeUserPointer(handles), num_handles, + flags); +} + +MojoResult MojoSystemImplReadMessage(MojoSystemImpl system, + MojoHandle message_pipe_handle, + void* bytes, + uint32_t* num_bytes, + MojoHandle* handles, + uint32_t* num_handles, + MojoReadMessageFlags flags) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->ReadMessage(message_pipe_handle, MakeUserPointer(bytes), + MakeUserPointer(num_bytes), MakeUserPointer(handles), + MakeUserPointer(num_handles), flags); +} + +MojoResult MojoSystemImplCreateDataPipe( + MojoSystemImpl system, + const MojoCreateDataPipeOptions* options, + MojoHandle* data_pipe_producer_handle, + MojoHandle* data_pipe_consumer_handle) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->CreateDataPipe(MakeUserPointer(options), + MakeUserPointer(data_pipe_producer_handle), + MakeUserPointer(data_pipe_consumer_handle)); +} + +MojoResult MojoSystemImplWriteData(MojoSystemImpl system, + MojoHandle data_pipe_producer_handle, + const void* elements, + uint32_t* num_elements, + MojoWriteDataFlags flags) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->WriteData(data_pipe_producer_handle, MakeUserPointer(elements), + MakeUserPointer(num_elements), flags); +} + +MojoResult MojoSystemImplBeginWriteData(MojoSystemImpl system, + MojoHandle data_pipe_producer_handle, + void** buffer, + uint32_t* buffer_num_elements, + MojoWriteDataFlags flags) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->BeginWriteData(data_pipe_producer_handle, + MakeUserPointer(buffer), + MakeUserPointer(buffer_num_elements), flags); +} + +MojoResult MojoSystemImplEndWriteData(MojoSystemImpl system, + MojoHandle data_pipe_producer_handle, + uint32_t num_elements_written) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->EndWriteData(data_pipe_producer_handle, num_elements_written); +} + +MojoResult MojoSystemImplReadData(MojoSystemImpl system, + MojoHandle data_pipe_consumer_handle, + void* elements, + uint32_t* num_elements, + MojoReadDataFlags flags) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->ReadData(data_pipe_consumer_handle, MakeUserPointer(elements), + MakeUserPointer(num_elements), flags); +} + +MojoResult MojoSystemImplBeginReadData(MojoSystemImpl system, + MojoHandle data_pipe_consumer_handle, + const void** buffer, + uint32_t* buffer_num_elements, + MojoReadDataFlags flags) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->BeginReadData(data_pipe_consumer_handle, MakeUserPointer(buffer), + MakeUserPointer(buffer_num_elements), flags); +} + +MojoResult MojoSystemImplEndReadData(MojoSystemImpl system, + MojoHandle data_pipe_consumer_handle, + uint32_t num_elements_read) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->EndReadData(data_pipe_consumer_handle, num_elements_read); +} + +MojoResult MojoSystemImplCreateSharedBuffer( + MojoSystemImpl system, + const MojoCreateSharedBufferOptions* options, + uint64_t num_bytes, + MojoHandle* shared_buffer_handle) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->CreateSharedBuffer(MakeUserPointer(options), num_bytes, + MakeUserPointer(shared_buffer_handle)); +} + +MojoResult MojoSystemImplDuplicateBufferHandle( + MojoSystemImpl system, + MojoHandle buffer_handle, + const MojoDuplicateBufferHandleOptions* options, + MojoHandle* new_buffer_handle) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->DuplicateBufferHandle(buffer_handle, MakeUserPointer(options), + MakeUserPointer(new_buffer_handle)); +} + +MojoResult MojoSystemImplMapBuffer(MojoSystemImpl system, + MojoHandle buffer_handle, + uint64_t offset, + uint64_t num_bytes, + void** buffer, + MojoMapBufferFlags flags) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->MapBuffer(buffer_handle, offset, num_bytes, + MakeUserPointer(buffer), flags); +} + +MojoResult MojoSystemImplUnmapBuffer(MojoSystemImpl system, void* buffer) { + mojo::system::Core* core = static_cast<mojo::system::Core*>(system); + DCHECK(core); + return core->UnmapBuffer(MakeUserPointer(buffer)); +} + +} // extern "C"
diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc index 80c3d36..887a9a7 100644 --- a/mojo/edk/system/core.cc +++ b/mojo/edk/system/core.cc
@@ -97,6 +97,15 @@ return handle_table_.GetDispatcher(handle); } +MojoResult Core::GetAndRemoveDispatcher(MojoHandle handle, + scoped_refptr<Dispatcher>* dispatcher) { + if (handle == MOJO_HANDLE_INVALID) + return MOJO_RESULT_INVALID_ARGUMENT; + + base::AutoLock locker(handle_table_lock_); + return handle_table_.GetAndRemoveDispatcher(handle, dispatcher); +} + MojoResult Core::AsyncWait(MojoHandle handle, MojoHandleSignals signals, const base::Callback<void(MojoResult)>& callback) {
diff --git a/mojo/edk/system/core.h b/mojo/edk/system/core.h index aadfb66..0c38008 100644 --- a/mojo/edk/system/core.h +++ b/mojo/edk/system/core.h
@@ -52,6 +52,15 @@ // invalid. scoped_refptr<Dispatcher> GetDispatcher(MojoHandle handle); + // Like |GetDispatcher()|, but also removes the handle from the handle table. + // On success, gets the dispatcher for a given handle (which should not be + // |MOJO_HANDLE_INVALID|) and removes it. (On failure, returns an appropriate + // result (and leaves |dispatcher| alone), namely + // |MOJO_RESULT_INVALID_ARGUMENT| if there's no dispatcher for the given + // handle or |MOJO_RESULT_BUSY| if the handle is marked as busy.) + MojoResult GetAndRemoveDispatcher(MojoHandle handle, + scoped_refptr<Dispatcher>* dispatcher); + // Watches on the given handle for the given signals, calling |callback| when // a signal is satisfied or when all signals become unsatisfiable. |callback| // must satisfy stringent requirements -- see |Awakable::Awake()| in
diff --git a/mojo/edk/test/BUILD.gn b/mojo/edk/test/BUILD.gn index e8f55ad..8735708 100644 --- a/mojo/edk/test/BUILD.gn +++ b/mojo/edk/test/BUILD.gn
@@ -90,6 +90,7 @@ ":mojo_public_system_perftests", ":mojo_public_system_unittests", ":mojo_public_utility_unittests", + ":mojo_system_impl_private_unittests", ] } @@ -134,3 +135,10 @@ "../../public/cpp/utility/tests", ] } + +test("mojo_system_impl_private_unittests") { + deps = [ + ":run_all_unittests", + "../../public/platform/native:system_impl_private_tests", + ] +}