summaryrefslogtreecommitdiffstats
path: root/mojo
diff options
context:
space:
mode:
Diffstat (limited to 'mojo')
-rw-r--r--mojo/system/core_impl.cc53
-rw-r--r--mojo/system/core_impl_unittest.cc2
-rw-r--r--mojo/system/dispatcher.cc40
-rw-r--r--mojo/system/dispatcher.h17
-rw-r--r--mojo/system/dispatcher_unittest.cc13
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);