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
parent a5961436
...@@ -162,10 +162,14 @@ MojoResult CoreImpl::CreateMessagePipe(MojoHandle* message_pipe_handle0, ...@@ -162,10 +162,14 @@ MojoResult CoreImpl::CreateMessagePipe(MojoHandle* message_pipe_handle0,
{ {
base::AutoLock locker(handle_table_lock_); 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); h0 = AddDispatcherNoLock(dispatcher0);
if (h0 == MOJO_HANDLE_INVALID) if (h0 == MOJO_HANDLE_INVALID)
return MOJO_RESULT_RESOURCE_EXHAUSTED; return MOJO_RESULT_RESOURCE_EXHAUSTED;
// TODO(vtl): crbug.com/345911: On failure, we should close both dispatchers
// (outside the table lock).
h1 = AddDispatcherNoLock(dispatcher1); h1 = AddDispatcherNoLock(dispatcher1);
if (h1 == MOJO_HANDLE_INVALID) { if (h1 == MOJO_HANDLE_INVALID) {
handle_table_.erase(h0); handle_table_.erase(h0);
...@@ -359,6 +363,8 @@ MojoResult CoreImpl::ReadMessage(MojoHandle message_pipe_handle, ...@@ -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 // TODO(vtl): What should we do if we hit the maximum handle table size
// here? Currently, we'll just fill in those handles with // here? Currently, we'll just fill in those handles with
// |MOJO_HANDLE_INVALID| (and return success anyway). // |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]); handles[i] = AddDispatcherNoLock(dispatchers[i]);
LOG_IF(ERROR, handles[i] == MOJO_HANDLE_INVALID) LOG_IF(ERROR, handles[i] == MOJO_HANDLE_INVALID)
<< "Failed to add dispatcher (" << dispatchers[i].get() << ")"; << "Failed to add dispatcher (" << dispatchers[i].get() << ")";
...@@ -398,10 +404,14 @@ MojoResult CoreImpl::CreateDataPipe(const MojoCreateDataPipeOptions* options, ...@@ -398,10 +404,14 @@ MojoResult CoreImpl::CreateDataPipe(const MojoCreateDataPipeOptions* options,
{ {
base::AutoLock locker(handle_table_lock_); 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); producer_handle = AddDispatcherNoLock(producer_dispatcher);
if (producer_handle == MOJO_HANDLE_INVALID) if (producer_handle == MOJO_HANDLE_INVALID)
return MOJO_RESULT_RESOURCE_EXHAUSTED; 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); consumer_handle = AddDispatcherNoLock(consumer_dispatcher);
if (consumer_handle == MOJO_HANDLE_INVALID) { if (consumer_handle == MOJO_HANDLE_INVALID) {
handle_table_.erase(producer_handle); handle_table_.erase(producer_handle);
...@@ -499,9 +509,32 @@ MojoResult CoreImpl::DuplicateBufferHandle( ...@@ -499,9 +509,32 @@ MojoResult CoreImpl::DuplicateBufferHandle(
MojoHandle buffer_handle, MojoHandle buffer_handle,
const MojoDuplicateBufferHandleOptions* options, const MojoDuplicateBufferHandleOptions* options,
MojoHandle* new_buffer_handle) { MojoHandle* new_buffer_handle) {
// TODO(vtl) scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle));
NOTIMPLEMENTED(); if (!dispatcher.get())
return MOJO_RESULT_UNIMPLEMENTED; 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, MojoResult CoreImpl::MapBuffer(MojoHandle buffer_handle,
...@@ -509,9 +542,17 @@ MojoResult CoreImpl::MapBuffer(MojoHandle buffer_handle, ...@@ -509,9 +542,17 @@ MojoResult CoreImpl::MapBuffer(MojoHandle buffer_handle,
uint64_t num_bytes, uint64_t num_bytes,
void** buffer, void** buffer,
MojoMapBufferFlags flags) { MojoMapBufferFlags flags) {
// TODO(vtl) scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle));
NOTIMPLEMENTED(); if (!dispatcher.get())
return MOJO_RESULT_UNIMPLEMENTED; 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) { MojoResult CoreImpl::UnmapBuffer(void* buffer) {
......
...@@ -874,6 +874,8 @@ TEST_F(CoreImplTest, MessagePipeBasicLocalHandlePassing2) { ...@@ -874,6 +874,8 @@ TEST_F(CoreImplTest, MessagePipeBasicLocalHandlePassing2) {
EXPECT_EQ(MOJO_RESULT_OK, core()->Close(ch)); EXPECT_EQ(MOJO_RESULT_OK, core()->Close(ch));
} }
// TODO(vtl): Test |DuplicateBufferHandle()| and |MapBuffer()|.
} // namespace } // namespace
} // namespace system } // namespace system
} // namespace mojo } // namespace mojo
...@@ -125,6 +125,27 @@ MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) { ...@@ -125,6 +125,27 @@ MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) {
return EndReadDataImplNoLock(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, MojoResult Dispatcher::AddWaiter(Waiter* waiter,
MojoWaitFlags flags, MojoWaitFlags flags,
MojoResult wake_result) { MojoResult wake_result) {
...@@ -240,6 +261,25 @@ MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_bytes_read*/) { ...@@ -240,6 +261,25 @@ MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_bytes_read*/) {
return MOJO_RESULT_INVALID_ARGUMENT; 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*/, MojoResult Dispatcher::AddWaiterImplNoLock(Waiter* /*waiter*/,
MojoWaitFlags /*flags*/, MojoWaitFlags /*flags*/,
MojoResult /*wake_result*/) { MojoResult /*wake_result*/) {
......
...@@ -91,6 +91,16 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher : ...@@ -91,6 +91,16 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
uint32_t* buffer_num_bytes, uint32_t* buffer_num_bytes,
MojoReadDataFlags flags); MojoReadDataFlags flags);
MojoResult EndReadData(uint32_t num_bytes_read); 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 // 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 // object changes state to satisfy |flags| with result |wake_result| (which
...@@ -172,6 +182,13 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher : ...@@ -172,6 +182,13 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
uint32_t* buffer_num_bytes, uint32_t* buffer_num_bytes,
MojoReadDataFlags flags); MojoReadDataFlags flags);
virtual MojoResult EndReadDataImplNoLock(uint32_t num_bytes_read); 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, virtual MojoResult AddWaiterImplNoLock(Waiter* waiter,
MojoWaitFlags flags, MojoWaitFlags flags,
MojoResult wake_result); MojoResult wake_result);
......
...@@ -104,6 +104,8 @@ class ThreadSafetyStressThread : public base::SimpleThread { ...@@ -104,6 +104,8 @@ class ThreadSafetyStressThread : public base::SimpleThread {
READ_DATA, READ_DATA,
BEGIN_READ_DATA, BEGIN_READ_DATA,
END_READ_DATA, END_READ_DATA,
DUPLICATE_BUFFER_HANDLE,
MAP_BUFFER,
ADD_WAITER, ADD_WAITER,
REMOVE_WAITER, REMOVE_WAITER,
...@@ -174,6 +176,17 @@ class ThreadSafetyStressThread : public base::SimpleThread { ...@@ -174,6 +176,17 @@ class ThreadSafetyStressThread : public base::SimpleThread {
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
dispatcher_->EndReadData(0)); dispatcher_->EndReadData(0));
break; 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: { case ADD_WAITER: {
MojoResult r = dispatcher_->AddWaiter(&waiter_, MojoResult r = dispatcher_->AddWaiter(&waiter_,
MOJO_WAIT_FLAG_EVERYTHING, 0); MOJO_WAIT_FLAG_EVERYTHING, 0);
......
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