Index: mojo/edk/system/dispatcher.cc |
diff --git a/third_party/mojo/src/mojo/edk/system/dispatcher.cc b/mojo/edk/system/dispatcher.cc |
similarity index 70% |
copy from third_party/mojo/src/mojo/edk/system/dispatcher.cc |
copy to mojo/edk/system/dispatcher.cc |
index b4487579a3474837ce95df610d0e8a2784791bb3..e7426e513f284b9becdb38f31f72d4cb8bd0c331 100644 |
--- a/third_party/mojo/src/mojo/edk/system/dispatcher.cc |
+++ b/mojo/edk/system/dispatcher.cc |
@@ -2,18 +2,18 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "third_party/mojo/src/mojo/edk/system/dispatcher.h" |
+#include "mojo/edk/system/dispatcher.h" |
#include "base/logging.h" |
-#include "third_party/mojo/src/mojo/edk/system/configuration.h" |
-#include "third_party/mojo/src/mojo/edk/system/data_pipe_consumer_dispatcher.h" |
-#include "third_party/mojo/src/mojo/edk/system/data_pipe_producer_dispatcher.h" |
-#include "third_party/mojo/src/mojo/edk/system/message_pipe_dispatcher.h" |
-#include "third_party/mojo/src/mojo/edk/system/platform_handle_dispatcher.h" |
-#include "third_party/mojo/src/mojo/edk/system/shared_buffer_dispatcher.h" |
+#include "mojo/edk/system/configuration.h" |
+#include "mojo/edk/system/data_pipe_consumer_dispatcher.h" |
+#include "mojo/edk/system/data_pipe_producer_dispatcher.h" |
+#include "mojo/edk/system/message_pipe_dispatcher.h" |
+#include "mojo/edk/system/platform_handle_dispatcher.h" |
+#include "mojo/edk/system/shared_buffer_dispatcher.h" |
namespace mojo { |
-namespace system { |
+namespace edk { |
namespace test { |
@@ -26,18 +26,22 @@ DispatcherTransport DispatcherTryStartTransport(Dispatcher* dispatcher) { |
// Dispatcher ------------------------------------------------------------------ |
-// TODO(vtl): The thread-safety analyzer isn't smart enough to deal with the |
-// fact that we give up if |TryLock()| fails. |
// static |
DispatcherTransport Dispatcher::HandleTableAccess::TryStartTransport( |
- Dispatcher* dispatcher) MOJO_NO_THREAD_SAFETY_ANALYSIS { |
+ Dispatcher* dispatcher) { |
DCHECK(dispatcher); |
- if (!dispatcher->mutex_.TryLock()) |
- return DispatcherTransport(); |
+ // Our dispatcher implementations hop to IO thread on initialization, so it's |
+ // valid that while their RawChannel os being initialized on IO thread, the |
+ // dispatcher is being sent. We handle this by just acquiring the lock. |
+ |
+ // See comment in header for why we need this. |
+ dispatcher->TransportStarted(); |
+ |
+ dispatcher->lock_.Acquire(); |
// We shouldn't race with things that close dispatchers, since closing can |
- // only take place either under |handle_table_mutex_| or when the handle is |
+ // only take place either under |handle_table_lock_| or when the handle is |
// marked as busy. |
DCHECK(!dispatcher->is_closed_); |
@@ -47,58 +51,57 @@ DispatcherTransport Dispatcher::HandleTableAccess::TryStartTransport( |
// static |
void Dispatcher::TransportDataAccess::StartSerialize( |
Dispatcher* dispatcher, |
- Channel* channel, |
size_t* max_size, |
size_t* max_platform_handles) { |
DCHECK(dispatcher); |
- dispatcher->StartSerialize(channel, max_size, max_platform_handles); |
+ dispatcher->StartSerialize(max_size, max_platform_handles); |
} |
// static |
bool Dispatcher::TransportDataAccess::EndSerializeAndClose( |
Dispatcher* dispatcher, |
- Channel* channel, |
void* destination, |
size_t* actual_size, |
- embedder::PlatformHandleVector* platform_handles) { |
+ PlatformHandleVector* platform_handles) { |
DCHECK(dispatcher); |
- return dispatcher->EndSerializeAndClose(channel, destination, actual_size, |
+ return dispatcher->EndSerializeAndClose(destination, actual_size, |
platform_handles); |
} |
// static |
scoped_refptr<Dispatcher> Dispatcher::TransportDataAccess::Deserialize( |
- Channel* channel, |
int32_t type, |
const void* source, |
size_t size, |
- embedder::PlatformHandleVector* platform_handles) { |
+ PlatformHandleVector* platform_handles) { |
switch (static_cast<Dispatcher::Type>(type)) { |
case Type::UNKNOWN: |
DVLOG(2) << "Deserializing invalid handle"; |
return nullptr; |
case Type::MESSAGE_PIPE: |
- return scoped_refptr<Dispatcher>( |
- MessagePipeDispatcher::Deserialize(channel, source, size)); |
+ return scoped_refptr<Dispatcher>(MessagePipeDispatcher::Deserialize( |
+ source, size, platform_handles)); |
case Type::DATA_PIPE_PRODUCER: |
return scoped_refptr<Dispatcher>( |
- DataPipeProducerDispatcher::Deserialize(channel, source, size)); |
+ DataPipeProducerDispatcher::Deserialize( |
+ source, size, platform_handles)); |
case Type::DATA_PIPE_CONSUMER: |
return scoped_refptr<Dispatcher>( |
- DataPipeConsumerDispatcher::Deserialize(channel, source, size)); |
+ DataPipeConsumerDispatcher::Deserialize( |
+ source, size, platform_handles)); |
case Type::SHARED_BUFFER: |
return scoped_refptr<Dispatcher>(SharedBufferDispatcher::Deserialize( |
- channel, source, size, platform_handles)); |
+ source, size, platform_handles)); |
case Type::PLATFORM_HANDLE: |
return scoped_refptr<Dispatcher>(PlatformHandleDispatcher::Deserialize( |
- channel, source, size, platform_handles)); |
+ source, size, platform_handles)); |
} |
LOG(WARNING) << "Unknown dispatcher type " << type; |
return nullptr; |
} |
MojoResult Dispatcher::Close() { |
- MutexLocker locker(&mutex_); |
+ base::AutoLock locker(lock_); |
if (is_closed_) |
return MOJO_RESULT_INVALID_ARGUMENT; |
@@ -107,7 +110,7 @@ MojoResult Dispatcher::Close() { |
} |
MojoResult Dispatcher::WriteMessage( |
- UserPointer<const void> bytes, |
+ const void* bytes, |
uint32_t num_bytes, |
std::vector<DispatcherTransport>* transports, |
MojoWriteMessageFlags flags) { |
@@ -115,22 +118,22 @@ MojoResult Dispatcher::WriteMessage( |
(transports->size() > 0 && |
transports->size() < GetConfiguration().max_message_num_handles)); |
- MutexLocker locker(&mutex_); |
+ base::AutoLock locker(lock_); |
if (is_closed_) |
return MOJO_RESULT_INVALID_ARGUMENT; |
return WriteMessageImplNoLock(bytes, num_bytes, transports, flags); |
} |
-MojoResult Dispatcher::ReadMessage(UserPointer<void> bytes, |
- UserPointer<uint32_t> num_bytes, |
+MojoResult Dispatcher::ReadMessage(void* bytes, |
+ uint32_t* num_bytes, |
DispatcherVector* dispatchers, |
uint32_t* num_dispatchers, |
MojoReadMessageFlags flags) { |
DCHECK(!num_dispatchers || *num_dispatchers == 0 || |
(dispatchers && dispatchers->empty())); |
- MutexLocker locker(&mutex_); |
+ base::AutoLock locker(lock_); |
if (is_closed_) |
return MOJO_RESULT_INVALID_ARGUMENT; |
@@ -138,20 +141,20 @@ MojoResult Dispatcher::ReadMessage(UserPointer<void> bytes, |
flags); |
} |
-MojoResult Dispatcher::WriteData(UserPointer<const void> elements, |
- UserPointer<uint32_t> num_bytes, |
+MojoResult Dispatcher::WriteData(const void* elements, |
+ uint32_t* num_bytes, |
MojoWriteDataFlags flags) { |
- MutexLocker locker(&mutex_); |
+ base::AutoLock locker(lock_); |
if (is_closed_) |
return MOJO_RESULT_INVALID_ARGUMENT; |
return WriteDataImplNoLock(elements, num_bytes, flags); |
} |
-MojoResult Dispatcher::BeginWriteData(UserPointer<void*> buffer, |
- UserPointer<uint32_t> buffer_num_bytes, |
+MojoResult Dispatcher::BeginWriteData(void** buffer, |
+ uint32_t* buffer_num_bytes, |
MojoWriteDataFlags flags) { |
- MutexLocker locker(&mutex_); |
+ base::AutoLock locker(lock_); |
if (is_closed_) |
return MOJO_RESULT_INVALID_ARGUMENT; |
@@ -159,27 +162,27 @@ MojoResult Dispatcher::BeginWriteData(UserPointer<void*> buffer, |
} |
MojoResult Dispatcher::EndWriteData(uint32_t num_bytes_written) { |
- MutexLocker locker(&mutex_); |
+ base::AutoLock locker(lock_); |
if (is_closed_) |
return MOJO_RESULT_INVALID_ARGUMENT; |
return EndWriteDataImplNoLock(num_bytes_written); |
} |
-MojoResult Dispatcher::ReadData(UserPointer<void> elements, |
- UserPointer<uint32_t> num_bytes, |
+MojoResult Dispatcher::ReadData(void* elements, |
+ uint32_t* num_bytes, |
MojoReadDataFlags flags) { |
- MutexLocker locker(&mutex_); |
+ base::AutoLock locker(lock_); |
if (is_closed_) |
return MOJO_RESULT_INVALID_ARGUMENT; |
return ReadDataImplNoLock(elements, num_bytes, flags); |
} |
-MojoResult Dispatcher::BeginReadData(UserPointer<const void*> buffer, |
- UserPointer<uint32_t> buffer_num_bytes, |
+MojoResult Dispatcher::BeginReadData(const void** buffer, |
+ uint32_t* buffer_num_bytes, |
MojoReadDataFlags flags) { |
- MutexLocker locker(&mutex_); |
+ base::AutoLock locker(lock_); |
if (is_closed_) |
return MOJO_RESULT_INVALID_ARGUMENT; |
@@ -187,7 +190,7 @@ MojoResult Dispatcher::BeginReadData(UserPointer<const void*> buffer, |
} |
MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) { |
- MutexLocker locker(&mutex_); |
+ base::AutoLock locker(lock_); |
if (is_closed_) |
return MOJO_RESULT_INVALID_ARGUMENT; |
@@ -195,9 +198,9 @@ MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) { |
} |
MojoResult Dispatcher::DuplicateBufferHandle( |
- UserPointer<const MojoDuplicateBufferHandleOptions> options, |
+ const MojoDuplicateBufferHandleOptions* options, |
scoped_refptr<Dispatcher>* new_dispatcher) { |
- MutexLocker locker(&mutex_); |
+ base::AutoLock locker(lock_); |
if (is_closed_) |
return MOJO_RESULT_INVALID_ARGUMENT; |
@@ -208,8 +211,8 @@ MojoResult Dispatcher::MapBuffer( |
uint64_t offset, |
uint64_t num_bytes, |
MojoMapBufferFlags flags, |
- scoped_ptr<embedder::PlatformSharedBufferMapping>* mapping) { |
- MutexLocker locker(&mutex_); |
+ scoped_ptr<PlatformSharedBufferMapping>* mapping) { |
+ base::AutoLock locker(lock_); |
if (is_closed_) |
return MOJO_RESULT_INVALID_ARGUMENT; |
@@ -217,7 +220,7 @@ MojoResult Dispatcher::MapBuffer( |
} |
HandleSignalsState Dispatcher::GetHandleSignalsState() const { |
- MutexLocker locker(&mutex_); |
+ base::AutoLock locker(lock_); |
if (is_closed_) |
return HandleSignalsState(); |
@@ -228,7 +231,7 @@ MojoResult Dispatcher::AddAwakable(Awakable* awakable, |
MojoHandleSignals signals, |
uint32_t context, |
HandleSignalsState* signals_state) { |
- MutexLocker locker(&mutex_); |
+ base::AutoLock locker(lock_); |
if (is_closed_) { |
if (signals_state) |
*signals_state = HandleSignalsState(); |
@@ -240,7 +243,7 @@ MojoResult Dispatcher::AddAwakable(Awakable* awakable, |
void Dispatcher::RemoveAwakable(Awakable* awakable, |
HandleSignalsState* handle_signals_state) { |
- MutexLocker locker(&mutex_); |
+ base::AutoLock locker(lock_); |
if (is_closed_) { |
if (handle_signals_state) |
*handle_signals_state = HandleSignalsState(); |
@@ -259,98 +262,98 @@ Dispatcher::~Dispatcher() { |
} |
void Dispatcher::CancelAllAwakablesNoLock() { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(is_closed_); |
// By default, waiting isn't supported. Only dispatchers that can be waited on |
// will do something nontrivial. |
} |
void Dispatcher::CloseImplNoLock() { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(is_closed_); |
// This may not need to do anything. Dispatchers should override this to do |
// any actual close-time cleanup necessary. |
} |
MojoResult Dispatcher::WriteMessageImplNoLock( |
- UserPointer<const void> /*bytes*/, |
+ const void* /*bytes*/, |
uint32_t /*num_bytes*/, |
std::vector<DispatcherTransport>* /*transports*/, |
MojoWriteMessageFlags /*flags*/) { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(!is_closed_); |
// By default, not supported. Only needed for message pipe dispatchers. |
return MOJO_RESULT_INVALID_ARGUMENT; |
} |
MojoResult Dispatcher::ReadMessageImplNoLock( |
- UserPointer<void> /*bytes*/, |
- UserPointer<uint32_t> /*num_bytes*/, |
+ void* /*bytes*/, |
+ uint32_t* /*num_bytes*/, |
DispatcherVector* /*dispatchers*/, |
uint32_t* /*num_dispatchers*/, |
MojoReadMessageFlags /*flags*/) { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(!is_closed_); |
// By default, not supported. Only needed for message pipe dispatchers. |
return MOJO_RESULT_INVALID_ARGUMENT; |
} |
-MojoResult Dispatcher::WriteDataImplNoLock(UserPointer<const void> /*elements*/, |
- UserPointer<uint32_t> /*num_bytes*/, |
+MojoResult Dispatcher::WriteDataImplNoLock(const void* /*elements*/, |
+ uint32_t* /*num_bytes*/, |
MojoWriteDataFlags /*flags*/) { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(!is_closed_); |
// By default, not supported. Only needed for data pipe dispatchers. |
return MOJO_RESULT_INVALID_ARGUMENT; |
} |
MojoResult Dispatcher::BeginWriteDataImplNoLock( |
- UserPointer<void*> /*buffer*/, |
- UserPointer<uint32_t> /*buffer_num_bytes*/, |
+ void** /*buffer*/, |
+ uint32_t* /*buffer_num_bytes*/, |
MojoWriteDataFlags /*flags*/) { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(!is_closed_); |
// By default, not supported. Only needed for data pipe dispatchers. |
return MOJO_RESULT_INVALID_ARGUMENT; |
} |
MojoResult Dispatcher::EndWriteDataImplNoLock(uint32_t /*num_bytes_written*/) { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(!is_closed_); |
// By default, not supported. Only needed for data pipe dispatchers. |
return MOJO_RESULT_INVALID_ARGUMENT; |
} |
-MojoResult Dispatcher::ReadDataImplNoLock(UserPointer<void> /*elements*/, |
- UserPointer<uint32_t> /*num_bytes*/, |
+MojoResult Dispatcher::ReadDataImplNoLock(void* /*elements*/, |
+ uint32_t* /*num_bytes*/, |
MojoReadDataFlags /*flags*/) { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(!is_closed_); |
// By default, not supported. Only needed for data pipe dispatchers. |
return MOJO_RESULT_INVALID_ARGUMENT; |
} |
MojoResult Dispatcher::BeginReadDataImplNoLock( |
- UserPointer<const void*> /*buffer*/, |
- UserPointer<uint32_t> /*buffer_num_bytes*/, |
+ const void** /*buffer*/, |
+ uint32_t* /*buffer_num_bytes*/, |
MojoReadDataFlags /*flags*/) { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(!is_closed_); |
// By default, not supported. Only needed for data pipe dispatchers. |
return MOJO_RESULT_INVALID_ARGUMENT; |
} |
MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_bytes_read*/) { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(!is_closed_); |
// By default, not supported. Only needed for data pipe dispatchers. |
return MOJO_RESULT_INVALID_ARGUMENT; |
} |
MojoResult Dispatcher::DuplicateBufferHandleImplNoLock( |
- UserPointer<const MojoDuplicateBufferHandleOptions> /*options*/, |
+ const MojoDuplicateBufferHandleOptions* /*options*/, |
scoped_refptr<Dispatcher>* /*new_dispatcher*/) { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(!is_closed_); |
// By default, not supported. Only needed for buffer dispatchers. |
return MOJO_RESULT_INVALID_ARGUMENT; |
@@ -360,15 +363,15 @@ MojoResult Dispatcher::MapBufferImplNoLock( |
uint64_t /*offset*/, |
uint64_t /*num_bytes*/, |
MojoMapBufferFlags /*flags*/, |
- scoped_ptr<embedder::PlatformSharedBufferMapping>* /*mapping*/) { |
- mutex_.AssertHeld(); |
+ scoped_ptr<PlatformSharedBufferMapping>* /*mapping*/) { |
+ lock_.AssertAcquired(); |
DCHECK(!is_closed_); |
// By default, not supported. Only needed for buffer dispatchers. |
return MOJO_RESULT_INVALID_ARGUMENT; |
} |
HandleSignalsState Dispatcher::GetHandleSignalsStateImplNoLock() const { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(!is_closed_); |
// By default, waiting isn't supported. Only dispatchers that can be waited on |
// will do something nontrivial. |
@@ -380,7 +383,7 @@ MojoResult Dispatcher::AddAwakableImplNoLock( |
MojoHandleSignals /*signals*/, |
uint32_t /*context*/, |
HandleSignalsState* signals_state) { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(!is_closed_); |
// By default, waiting isn't supported. Only dispatchers that can be waited on |
// will do something nontrivial. |
@@ -391,7 +394,7 @@ MojoResult Dispatcher::AddAwakableImplNoLock( |
void Dispatcher::RemoveAwakableImplNoLock(Awakable* /*awakable*/, |
HandleSignalsState* signals_state) { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(!is_closed_); |
// By default, waiting isn't supported. Only dispatchers that can be waited on |
// will do something nontrivial. |
@@ -399,8 +402,7 @@ void Dispatcher::RemoveAwakableImplNoLock(Awakable* /*awakable*/, |
*signals_state = HandleSignalsState(); |
} |
-void Dispatcher::StartSerializeImplNoLock(Channel* /*channel*/, |
- size_t* max_size, |
+void Dispatcher::StartSerializeImplNoLock(size_t* max_size, |
size_t* max_platform_handles) { |
DCHECK(HasOneRef()); // Only one ref => no need to take the lock. |
DCHECK(!is_closed_); |
@@ -409,10 +411,9 @@ void Dispatcher::StartSerializeImplNoLock(Channel* /*channel*/, |
} |
bool Dispatcher::EndSerializeAndCloseImplNoLock( |
- Channel* /*channel*/, |
void* /*destination*/, |
size_t* /*actual_size*/, |
- embedder::PlatformHandleVector* /*platform_handles*/) { |
+ PlatformHandleVector* /*platform_handles*/) { |
DCHECK(HasOneRef()); // Only one ref => no need to take the lock. |
DCHECK(is_closed_); |
// By default, serializing isn't supported, so just close. |
@@ -421,7 +422,7 @@ bool Dispatcher::EndSerializeAndCloseImplNoLock( |
} |
bool Dispatcher::IsBusyNoLock() const { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(!is_closed_); |
// Most dispatchers support only "atomic" operations, so they are never busy |
// (in this sense). |
@@ -429,7 +430,7 @@ bool Dispatcher::IsBusyNoLock() const { |
} |
void Dispatcher::CloseNoLock() { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(!is_closed_); |
is_closed_ = true; |
@@ -439,7 +440,7 @@ void Dispatcher::CloseNoLock() { |
scoped_refptr<Dispatcher> |
Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() { |
- mutex_.AssertHeld(); |
+ lock_.AssertAcquired(); |
DCHECK(!is_closed_); |
is_closed_ = true; |
@@ -447,25 +448,18 @@ Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() { |
return CreateEquivalentDispatcherAndCloseImplNoLock(); |
} |
-void Dispatcher::StartSerialize(Channel* channel, |
- size_t* max_size, |
+void Dispatcher::StartSerialize(size_t* max_size, |
size_t* max_platform_handles) { |
- DCHECK(channel); |
DCHECK(max_size); |
DCHECK(max_platform_handles); |
- DCHECK(HasOneRef()); // Only one ref => no need to take the lock. |
DCHECK(!is_closed_); |
- StartSerializeImplNoLock(channel, max_size, max_platform_handles); |
+ StartSerializeImplNoLock(max_size, max_platform_handles); |
} |
-bool Dispatcher::EndSerializeAndClose( |
- Channel* channel, |
- void* destination, |
- size_t* actual_size, |
- embedder::PlatformHandleVector* platform_handles) { |
- DCHECK(channel); |
+bool Dispatcher::EndSerializeAndClose(void* destination, |
+ size_t* actual_size, |
+ PlatformHandleVector* platform_handles) { |
DCHECK(actual_size); |
- DCHECK(HasOneRef()); // Only one ref => no need to take the lock. |
DCHECK(!is_closed_); |
// Like other |...Close()| methods, we mark ourselves as closed before calling |
@@ -477,10 +471,10 @@ bool Dispatcher::EndSerializeAndClose( |
// See the comment above |EndSerializeAndCloseImplNoLock()|. In brief: Locking |
// isn't actually needed, but we need to satisfy assertions (which we don't |
// want to remove or weaken). |
- MutexLocker locker(&mutex_); |
+ base::AutoLock locker(lock_); |
#endif |
- return EndSerializeAndCloseImplNoLock(channel, destination, actual_size, |
+ return EndSerializeAndCloseImplNoLock(destination, actual_size, |
platform_handles); |
} |
@@ -488,9 +482,12 @@ bool Dispatcher::EndSerializeAndClose( |
void DispatcherTransport::End() { |
DCHECK(dispatcher_); |
- dispatcher_->mutex_.Unlock(); |
+ dispatcher_->lock_.Release(); |
+ |
+ dispatcher_->TransportEnded(); |
+ |
dispatcher_ = nullptr; |
} |
-} // namespace system |
+} // namespace edk |
} // namespace mojo |