Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / mojo / system / core_impl.cc
index 5bda3c8..51a5bef 100644 (file)
@@ -214,7 +214,7 @@ MojoResult CoreImpl::WriteMessage(MojoHandle message_pipe_handle,
   // without accessing the handle table. These can be dumb pointers, since their
   // entries in the handle table won't get removed (since they'll be marked as
   // busy).
-  std::vector<Dispatcher*> dispatchers(num_handles);
+  std::vector<DispatcherTransport> transports(num_handles);
 
   // When we pass handles, we have to try to take all their dispatchers' locks
   // and mark the handles as busy. If the call succeeds, we then remove the
@@ -250,22 +250,30 @@ MojoResult CoreImpl::WriteMessage(MojoHandle message_pipe_handle,
       // same handle from being sent multiple times in the same message.
       entries[i]->busy = true;
 
-      // Try to take the lock.
-      if (!entries[i]->dispatcher->lock().Try()) {
+      // Try to start the transport.
+      DispatcherTransport transport =
+          Dispatcher::CoreImplAccess::TryStartTransport(
+              entries[i]->dispatcher.get());
+      if (!transport.is_valid()) {
         // Unset the busy flag (since it won't be unset below).
         entries[i]->busy = false;
         error_result = MOJO_RESULT_BUSY;
         break;
       }
 
-      // We shouldn't race with things that close dispatchers, since closing can
-      // only take place either under |handle_table_lock_| or when the handle is
-      // marked as busy.
-      DCHECK(!entries[i]->dispatcher->is_closed_no_lock());
+      // Check if the dispatcher is busy (e.g., in a two-phase read/write).
+      // (Note that this must be done after the dispatcher's lock is acquired.)
+      if (transport.IsBusy()) {
+        // Unset the busy flag and end the transport (since it won't be done
+        // below).
+        entries[i]->busy = false;
+        transport.End();
+        error_result = MOJO_RESULT_BUSY;
+        break;
+      }
 
-      // Hang on to the pointer to the dispatcher (which we'll need to release
-      // the lock without going through the handle table).
-      dispatchers[i] = entries[i]->dispatcher;
+      // Hang on to the transport (which we'll need to end the transport).
+      transports[i] = transport;
     }
     if (i < num_handles) {
       DCHECK_NE(error_result, MOJO_RESULT_INTERNAL);
@@ -274,22 +282,19 @@ MojoResult CoreImpl::WriteMessage(MojoHandle message_pipe_handle,
       for (uint32_t j = 0; j < i; j++) {
         DCHECK(entries[j]->busy);
         entries[j]->busy = false;
-        entries[j]->dispatcher->lock().Release();
+        transports[j].End();
       }
       return error_result;
     }
   }
 
-  MojoResult rv = dispatcher->WriteMessage(bytes, num_bytes,
-                                           &dispatchers,
+  MojoResult rv = dispatcher->WriteMessage(bytes, num_bytes, &transports,
                                            flags);
 
   // We need to release the dispatcher locks before we take the handle table
   // lock.
-  for (uint32_t i = 0; i < num_handles; i++) {
-    dispatchers[i]->lock().AssertAcquired();
-    dispatchers[i]->lock().Release();
-  }
+  for (uint32_t i = 0; i < num_handles; i++)
+    transports[i].End();
 
   if (rv == MOJO_RESULT_OK) {
     base::AutoLock locker(handle_table_lock_);
@@ -355,6 +360,8 @@ MojoResult CoreImpl::ReadMessage(MojoHandle message_pipe_handle,
       // here? Currently, we'll just fill in those handles with
       // |MOJO_HANDLE_INVALID| (and return success anyway).
       handles[i] = AddDispatcherNoLock(dispatchers[i]);
+      LOG_IF(ERROR, handles[i] == MOJO_HANDLE_INVALID)
+          << "Failed to add dispatcher (" << dispatchers[i].get() << ")";
     }
   }
 
@@ -479,6 +486,40 @@ MojoResult CoreImpl::EndReadData(MojoHandle data_pipe_consumer_handle,
   return dispatcher->EndReadData(num_bytes_read);
 }
 
+MojoResult CoreImpl::CreateSharedBuffer(
+    const MojoCreateSharedBufferOptions* options,
+    uint64_t* num_bytes,
+    MojoHandle* shared_buffer_handle) {
+  // TODO(vtl)
+  NOTIMPLEMENTED();
+  return MOJO_RESULT_UNIMPLEMENTED;
+}
+
+MojoResult CoreImpl::DuplicateBufferHandle(
+    MojoHandle buffer_handle,
+    const MojoDuplicateBufferHandleOptions* options,
+    MojoHandle* new_buffer_handle) {
+  // TODO(vtl)
+  NOTIMPLEMENTED();
+  return MOJO_RESULT_UNIMPLEMENTED;
+}
+
+MojoResult CoreImpl::MapBuffer(MojoHandle buffer_handle,
+                               uint64_t offset,
+                               uint64_t num_bytes,
+                               void** buffer,
+                               MojoMapBufferFlags flags) {
+  // TODO(vtl)
+  NOTIMPLEMENTED();
+  return MOJO_RESULT_UNIMPLEMENTED;
+}
+
+MojoResult CoreImpl::UnmapBuffer(void* buffer) {
+  // TODO(vtl)
+  NOTIMPLEMENTED();
+  return MOJO_RESULT_UNIMPLEMENTED;
+}
+
 scoped_refptr<Dispatcher> CoreImpl::GetDispatcher(MojoHandle handle) {
   if (handle == MOJO_HANDLE_INVALID)
     return NULL;
@@ -493,11 +534,10 @@ scoped_refptr<Dispatcher> CoreImpl::GetDispatcher(MojoHandle handle) {
 
 MojoHandle CoreImpl::AddDispatcherNoLock(
     const scoped_refptr<Dispatcher>& dispatcher) {
-  DCHECK(dispatcher.get());
   handle_table_lock_.AssertAcquired();
   DCHECK_NE(next_handle_, MOJO_HANDLE_INVALID);
 
-  if (handle_table_.size() >= kMaxHandleTableSize)
+  if (!dispatcher.get() || handle_table_.size() >= kMaxHandleTableSize)
     return MOJO_HANDLE_INVALID;
 
   // TODO(vtl): Maybe we want to do something different/smarter. (Or maybe try