diff options
author | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-22 22:29:25 +0000 |
---|---|---|
committer | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-22 22:29:25 +0000 |
commit | fcbf4734e120fc08b0d279ed754a60b6c7de34c4 (patch) | |
tree | 9c4d8287593b7947bc1495fdb06d881e3461bf56 /mojo | |
parent | a59614368401333c56bc8f2eff5514c278ab0e7e (diff) | |
download | chromium_src-fcbf4734e120fc08b0d279ed754a60b6c7de34c4.zip chromium_src-fcbf4734e120fc08b0d279ed754a60b6c7de34c4.tar.gz chromium_src-fcbf4734e120fc08b0d279ed754a60b6c7de34c4.tar.bz2 |
Mojo: Add Dispatcher::{DuplicateBufferHandle,MapBuffer} methods.
We'll need them to implement shared memory.
(Also add TODOs for a bug that I spotted.)
R=darin@chromium.org
Review URL: https://codereview.chromium.org/169463012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@252827 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo')
-rw-r--r-- | mojo/system/core_impl.cc | 53 | ||||
-rw-r--r-- | mojo/system/core_impl_unittest.cc | 2 | ||||
-rw-r--r-- | mojo/system/dispatcher.cc | 40 | ||||
-rw-r--r-- | mojo/system/dispatcher.h | 17 | ||||
-rw-r--r-- | mojo/system/dispatcher_unittest.cc | 13 |
5 files changed, 119 insertions, 6 deletions
diff --git a/mojo/system/core_impl.cc b/mojo/system/core_impl.cc index 51a5bef..859617a 100644 --- a/mojo/system/core_impl.cc +++ b/mojo/system/core_impl.cc @@ -162,10 +162,14 @@ MojoResult CoreImpl::CreateMessagePipe(MojoHandle* message_pipe_handle0, { base::AutoLock locker(handle_table_lock_); + // TODO(vtl): crbug.com/345911: On failure, we should close the dispatcher + // (outside the table lock). h0 = AddDispatcherNoLock(dispatcher0); if (h0 == MOJO_HANDLE_INVALID) return MOJO_RESULT_RESOURCE_EXHAUSTED; + // TODO(vtl): crbug.com/345911: On failure, we should close both dispatchers + // (outside the table lock). h1 = AddDispatcherNoLock(dispatcher1); if (h1 == MOJO_HANDLE_INVALID) { handle_table_.erase(h0); @@ -359,6 +363,8 @@ MojoResult CoreImpl::ReadMessage(MojoHandle message_pipe_handle, // TODO(vtl): What should we do if we hit the maximum handle table size // here? Currently, we'll just fill in those handles with // |MOJO_HANDLE_INVALID| (and return success anyway). + // TODO(vtl): crbug.com/345911: On failure, we should close the dispatcher + // (outside the table lock). handles[i] = AddDispatcherNoLock(dispatchers[i]); LOG_IF(ERROR, handles[i] == MOJO_HANDLE_INVALID) << "Failed to add dispatcher (" << dispatchers[i].get() << ")"; @@ -398,10 +404,14 @@ MojoResult CoreImpl::CreateDataPipe(const MojoCreateDataPipeOptions* options, { base::AutoLock locker(handle_table_lock_); + // TODO(vtl): crbug.com/345911: On failure, we should close the dispatcher + // (outside the table lock). producer_handle = AddDispatcherNoLock(producer_dispatcher); if (producer_handle == MOJO_HANDLE_INVALID) return MOJO_RESULT_RESOURCE_EXHAUSTED; + // TODO(vtl): crbug.com/345911: On failure, we should close both dispatchers + // (outside the table lock). consumer_handle = AddDispatcherNoLock(consumer_dispatcher); if (consumer_handle == MOJO_HANDLE_INVALID) { handle_table_.erase(producer_handle); @@ -499,9 +509,32 @@ MojoResult CoreImpl::DuplicateBufferHandle( MojoHandle buffer_handle, const MojoDuplicateBufferHandleOptions* options, MojoHandle* new_buffer_handle) { - // TODO(vtl) - NOTIMPLEMENTED(); - return MOJO_RESULT_UNIMPLEMENTED; + scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); + if (!dispatcher.get()) + return MOJO_RESULT_INVALID_ARGUMENT; + + if (!VerifyUserPointer<MojoHandle>(new_buffer_handle, 1)) + return MOJO_RESULT_INVALID_ARGUMENT; + + scoped_refptr<Dispatcher> new_dispatcher; + MojoResult result = dispatcher->DuplicateBufferHandle(options, + &new_dispatcher); + if (result != MOJO_RESULT_OK) + return result; + + MojoHandle new_handle; + { + base::AutoLock locker(handle_table_lock_); + + // TODO(vtl): crbug.com/345911: On failure, we should close the dispatcher + // (outside the table lock). + new_handle = AddDispatcherNoLock(new_dispatcher); + if (new_handle == MOJO_HANDLE_INVALID) + return MOJO_RESULT_RESOURCE_EXHAUSTED; + } + + *new_buffer_handle = new_handle; + return MOJO_RESULT_OK; } MojoResult CoreImpl::MapBuffer(MojoHandle buffer_handle, @@ -509,9 +542,17 @@ MojoResult CoreImpl::MapBuffer(MojoHandle buffer_handle, uint64_t num_bytes, void** buffer, MojoMapBufferFlags flags) { - // TODO(vtl) - NOTIMPLEMENTED(); - return MOJO_RESULT_UNIMPLEMENTED; + scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); + if (!dispatcher.get()) + return MOJO_RESULT_INVALID_ARGUMENT; + + MojoResult result = dispatcher->MapBuffer(offset, num_bytes, buffer, flags); + if (result != MOJO_RESULT_OK) + return result; + + // TODO(vtl): Record the mapping. + + return MOJO_RESULT_OK; } MojoResult CoreImpl::UnmapBuffer(void* buffer) { diff --git a/mojo/system/core_impl_unittest.cc b/mojo/system/core_impl_unittest.cc index bd4807b..93dc860 100644 --- a/mojo/system/core_impl_unittest.cc +++ b/mojo/system/core_impl_unittest.cc @@ -874,6 +874,8 @@ TEST_F(CoreImplTest, MessagePipeBasicLocalHandlePassing2) { EXPECT_EQ(MOJO_RESULT_OK, core()->Close(ch)); } +// TODO(vtl): Test |DuplicateBufferHandle()| and |MapBuffer()|. + } // namespace } // namespace system } // namespace mojo diff --git a/mojo/system/dispatcher.cc b/mojo/system/dispatcher.cc index acf42ee..ac02b83 100644 --- a/mojo/system/dispatcher.cc +++ b/mojo/system/dispatcher.cc @@ -125,6 +125,27 @@ MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) { return EndReadDataImplNoLock(num_bytes_read); } +MojoResult Dispatcher::DuplicateBufferHandle( + const MojoDuplicateBufferHandleOptions* options, + scoped_refptr<Dispatcher>* new_dispatcher) { + base::AutoLock locker(lock_); + if (is_closed_) + return MOJO_RESULT_INVALID_ARGUMENT; + + return DuplicateBufferHandleImplNoLock(options, new_dispatcher); +} + +MojoResult Dispatcher::MapBuffer(uint64_t offset, + uint64_t num_bytes, + void** buffer, + MojoMapBufferFlags flags) { + base::AutoLock locker(lock_); + if (is_closed_) + return MOJO_RESULT_INVALID_ARGUMENT; + + return MapBufferImplNoLock(offset, num_bytes, buffer, flags); +} + MojoResult Dispatcher::AddWaiter(Waiter* waiter, MojoWaitFlags flags, MojoResult wake_result) { @@ -240,6 +261,25 @@ MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_bytes_read*/) { return MOJO_RESULT_INVALID_ARGUMENT; } +MojoResult Dispatcher::DuplicateBufferHandleImplNoLock( + const MojoDuplicateBufferHandleOptions* /*options*/, + scoped_refptr<Dispatcher>* /*new_dispatcher*/) { + lock_.AssertAcquired(); + DCHECK(!is_closed_); + // By default, not supported. Only needed for buffer dispatchers. + return MOJO_RESULT_INVALID_ARGUMENT; +} + +MojoResult Dispatcher::MapBufferImplNoLock(uint64_t /*offset*/, + uint64_t /*num_bytes*/, + void** /*buffer*/, + MojoMapBufferFlags /*flags*/) { + lock_.AssertAcquired(); + DCHECK(!is_closed_); + // By default, not supported. Only needed for buffer dispatchers. + return MOJO_RESULT_INVALID_ARGUMENT; +} + MojoResult Dispatcher::AddWaiterImplNoLock(Waiter* /*waiter*/, MojoWaitFlags /*flags*/, MojoResult /*wake_result*/) { diff --git a/mojo/system/dispatcher.h b/mojo/system/dispatcher.h index a1bd728..59e536a 100644 --- a/mojo/system/dispatcher.h +++ b/mojo/system/dispatcher.h @@ -91,6 +91,16 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher : uint32_t* buffer_num_bytes, MojoReadDataFlags flags); MojoResult EndReadData(uint32_t num_bytes_read); + // |options| may be null. |new_dispatcher| must not be null, but + // |*new_dispatcher| should be null (and will contain the dispatcher for the + // new handle on success). + MojoResult DuplicateBufferHandle( + const MojoDuplicateBufferHandleOptions* options, + scoped_refptr<Dispatcher>* new_dispatcher); + MojoResult MapBuffer(uint64_t offset, + uint64_t num_bytes, + void** buffer, + MojoMapBufferFlags flags); // Adds a waiter to this dispatcher. The waiter will be woken up when this // object changes state to satisfy |flags| with result |wake_result| (which @@ -172,6 +182,13 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher : uint32_t* buffer_num_bytes, MojoReadDataFlags flags); virtual MojoResult EndReadDataImplNoLock(uint32_t num_bytes_read); + virtual MojoResult DuplicateBufferHandleImplNoLock( + const MojoDuplicateBufferHandleOptions* options, + scoped_refptr<Dispatcher>* new_dispatcher); + virtual MojoResult MapBufferImplNoLock(uint64_t offset, + uint64_t num_bytes, + void** buffer, + MojoMapBufferFlags flags); virtual MojoResult AddWaiterImplNoLock(Waiter* waiter, MojoWaitFlags flags, MojoResult wake_result); diff --git a/mojo/system/dispatcher_unittest.cc b/mojo/system/dispatcher_unittest.cc index e6d672b..9a7bedc 100644 --- a/mojo/system/dispatcher_unittest.cc +++ b/mojo/system/dispatcher_unittest.cc @@ -104,6 +104,8 @@ class ThreadSafetyStressThread : public base::SimpleThread { READ_DATA, BEGIN_READ_DATA, END_READ_DATA, + DUPLICATE_BUFFER_HANDLE, + MAP_BUFFER, ADD_WAITER, REMOVE_WAITER, @@ -174,6 +176,17 @@ class ThreadSafetyStressThread : public base::SimpleThread { EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dispatcher_->EndReadData(0)); break; + case DUPLICATE_BUFFER_HANDLE: { + scoped_refptr<Dispatcher> unused; + EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + dispatcher_->DuplicateBufferHandle(NULL, &unused)); + break; + } + case MAP_BUFFER: + EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + dispatcher_->MapBuffer(0u, 0u, NULL, + MOJO_MAP_BUFFER_FLAG_NONE)); + break; case ADD_WAITER: { MojoResult r = dispatcher_->AddWaiter(&waiter_, MOJO_WAIT_FLAG_EVERYTHING, 0); |