Index: third_party/mojo/src/mojo/edk/system/master_connection_manager.cc |
diff --git a/third_party/mojo/src/mojo/edk/system/master_connection_manager.cc b/third_party/mojo/src/mojo/edk/system/master_connection_manager.cc |
index d756f734d797252ad464fef8ae02ded4c7cdb2fd..7e24a4a8248125f92b5ccafc183fc5bf764d2415 100644 |
--- a/third_party/mojo/src/mojo/edk/system/master_connection_manager.cc |
+++ b/third_party/mojo/src/mojo/edk/system/master_connection_manager.cc |
@@ -21,6 +21,8 @@ |
namespace mojo { |
namespace system { |
+namespace { |
+ |
const ProcessIdentifier kFirstSlaveProcessIdentifier = 2; |
static_assert(kMasterProcessIdentifier != kInvalidProcessIdentifier, |
@@ -30,6 +32,29 @@ static_assert(kFirstSlaveProcessIdentifier != kInvalidProcessIdentifier, |
static_assert(kMasterProcessIdentifier != kFirstSlaveProcessIdentifier, |
"Master and first slave process identifiers are the same"); |
+MessageInTransit::Subtype ConnectionManagerResultToMessageInTransitSubtype( |
+ ConnectionManager::Result result) { |
+ switch (result) { |
+ case ConnectionManager::Result::FAILURE: |
+ return MessageInTransit::Subtype::CONNECTION_MANAGER_ACK_FAILURE; |
+ case ConnectionManager::Result::SUCCESS: |
+ return MessageInTransit::Subtype::CONNECTION_MANAGER_ACK_SUCCESS; |
+ case ConnectionManager::Result::SUCCESS_CONNECT_SAME_PROCESS: |
+ return MessageInTransit::Subtype:: |
+ CONNECTION_MANAGER_ACK_SUCCESS_CONNECT_SAME_PROCESS; |
+ case ConnectionManager::Result::SUCCESS_CONNECT_NEW_CONNECTION: |
+ return MessageInTransit::Subtype:: |
+ CONNECTION_MANAGER_ACK_SUCCESS_CONNECT_NEW_CONNECTION; |
+ case ConnectionManager::Result::SUCCESS_CONNECT_REUSE_CONNECTION: |
+ return MessageInTransit::Subtype:: |
+ CONNECTION_MANAGER_ACK_SUCCESS_CONNECT_REUSE_CONNECTION; |
+ } |
+ NOTREACHED(); |
+ return MessageInTransit::Subtype::CONNECTION_MANAGER_ACK_FAILURE; |
+} |
+ |
+} // namespace |
+ |
// MasterConnectionManager::Helper --------------------------------------------- |
// |MasterConnectionManager::Helper| is not thread-safe, and must only be used |
@@ -115,28 +140,38 @@ void MasterConnectionManager::Helper::OnReadMessage( |
const ConnectionIdentifier* connection_id = |
reinterpret_cast<const ConnectionIdentifier*>(message_view.bytes()); |
- bool result; |
+ Result result = Result::FAILURE; |
ProcessIdentifier peer_process_identifier = kInvalidProcessIdentifier; |
embedder::ScopedPlatformHandle platform_handle; |
uint32_t num_bytes = 0; |
const void* bytes = nullptr; |
switch (message_view.subtype()) { |
case MessageInTransit::Subtype::CONNECTION_MANAGER_ALLOW_CONNECT: |
- result = owner_->AllowConnectImpl(process_identifier_, *connection_id); |
+ result = owner_->AllowConnectImpl(process_identifier_, *connection_id) |
+ ? Result::SUCCESS |
+ : Result::FAILURE; |
break; |
case MessageInTransit::Subtype::CONNECTION_MANAGER_CANCEL_CONNECT: |
- result = owner_->CancelConnectImpl(process_identifier_, *connection_id); |
+ result = owner_->CancelConnectImpl(process_identifier_, *connection_id) |
+ ? Result::SUCCESS |
+ : Result::FAILURE; |
break; |
- case MessageInTransit::Subtype::CONNECTION_MANAGER_CONNECT: |
+ case MessageInTransit::Subtype::CONNECTION_MANAGER_CONNECT: { |
result = owner_->ConnectImpl(process_identifier_, *connection_id, |
&peer_process_identifier, &platform_handle); |
+ DCHECK_NE(result, Result::SUCCESS); |
+ // TODO(vtl): FIXME -- currently, nothing should generate |
+ // SUCCESS_CONNECT_REUSE_CONNECTION. |
+ CHECK_NE(result, Result::SUCCESS_CONNECT_REUSE_CONNECTION); |
// Success acks for "connect" have the peer process identifier as data |
- // (and maybe also a platform handle). |
- if (result) { |
+ // (and also a platform handle in the case of "new connection" -- handled |
+ // further below). |
+ if (result != Result::FAILURE) { |
num_bytes = static_cast<uint32_t>(sizeof(peer_process_identifier)); |
bytes = &peer_process_identifier; |
} |
break; |
+ } |
default: |
LOG(ERROR) << "Invalid message subtype " << message_view.subtype(); |
FatalError(); // WARNING: This destroys us. |
@@ -145,22 +180,21 @@ void MasterConnectionManager::Helper::OnReadMessage( |
scoped_ptr<MessageInTransit> response(new MessageInTransit( |
MessageInTransit::Type::CONNECTION_MANAGER_ACK, |
- result ? MessageInTransit::Subtype::CONNECTION_MANAGER_ACK_SUCCESS |
- : MessageInTransit::Subtype::CONNECTION_MANAGER_ACK_FAILURE, |
- num_bytes, bytes)); |
+ ConnectionManagerResultToMessageInTransitSubtype(result), num_bytes, |
+ bytes)); |
- if (platform_handle.is_valid()) { |
- // Only success acks for "connect" *may* have a platform handle attached. |
- DCHECK(result); |
+ if (result == Result::SUCCESS_CONNECT_NEW_CONNECTION) { |
DCHECK_EQ(message_view.subtype(), |
MessageInTransit::Subtype::CONNECTION_MANAGER_CONNECT); |
- |
+ DCHECK(platform_handle.is_valid()); |
embedder::ScopedPlatformHandleVectorPtr platform_handles( |
new embedder::PlatformHandleVector()); |
platform_handles->push_back(platform_handle.release()); |
response->SetTransportData(make_scoped_ptr( |
new TransportData(platform_handles.Pass(), |
raw_channel_->GetSerializedPlatformHandleSize()))); |
+ } else { |
+ DCHECK(!platform_handle.is_valid()); |
} |
if (!raw_channel_->WriteMessage(response.Pass())) { |
@@ -261,7 +295,7 @@ ProcessIdentifier MasterConnectionManager::AddSlave( |
ProcessIdentifier slave_process_identifier; |
{ |
- base::AutoLock locker(lock_); |
+ MutexLocker locker(&mutex_); |
CHECK_NE(next_process_identifier_, kMasterProcessIdentifier); |
slave_process_identifier = next_process_identifier_; |
next_process_identifier_++; |
@@ -288,7 +322,7 @@ ProcessIdentifier MasterConnectionManager::AddSlaveAndBootstrap( |
ProcessIdentifier slave_process_identifier = |
AddSlave(slave_info, platform_handle.Pass()); |
- base::AutoLock locker(lock_); |
+ MutexLocker locker(&mutex_); |
DCHECK(pending_connections_.find(connection_id) == |
pending_connections_.end()); |
PendingConnectionInfo* info = |
@@ -328,11 +362,10 @@ bool MasterConnectionManager::CancelConnect( |
return CancelConnectImpl(kMasterProcessIdentifier, connection_id); |
} |
-bool MasterConnectionManager::Connect( |
+ConnectionManager::Result MasterConnectionManager::Connect( |
const ConnectionIdentifier& connection_id, |
ProcessIdentifier* peer_process_identifier, |
embedder::ScopedPlatformHandle* platform_handle) { |
- AssertNotOnPrivateThread(); |
return ConnectImpl(kMasterProcessIdentifier, connection_id, |
peer_process_identifier, platform_handle); |
} |
@@ -342,7 +375,7 @@ bool MasterConnectionManager::AllowConnectImpl( |
const ConnectionIdentifier& connection_id) { |
DCHECK_NE(process_identifier, kInvalidProcessIdentifier); |
- base::AutoLock locker(lock_); |
+ MutexLocker locker(&mutex_); |
auto it = pending_connections_.find(connection_id); |
if (it == pending_connections_.end()) { |
@@ -381,7 +414,7 @@ bool MasterConnectionManager::CancelConnectImpl( |
const ConnectionIdentifier& connection_id) { |
DCHECK_NE(process_identifier, kInvalidProcessIdentifier); |
- base::AutoLock locker(lock_); |
+ MutexLocker locker(&mutex_); |
auto it = pending_connections_.find(connection_id); |
if (it == pending_connections_.end()) { |
@@ -408,7 +441,7 @@ bool MasterConnectionManager::CancelConnectImpl( |
return true; |
} |
-bool MasterConnectionManager::ConnectImpl( |
+ConnectionManager::Result MasterConnectionManager::ConnectImpl( |
ProcessIdentifier process_identifier, |
const ConnectionIdentifier& connection_id, |
ProcessIdentifier* peer_process_identifier, |
@@ -418,7 +451,7 @@ bool MasterConnectionManager::ConnectImpl( |
DCHECK(platform_handle); |
DCHECK(!platform_handle->is_valid()); // Not technically wrong, but unlikely. |
- base::AutoLock locker(lock_); |
+ MutexLocker locker(&mutex_); |
auto it = pending_connections_.find(connection_id); |
if (it == pending_connections_.end()) { |
@@ -426,7 +459,7 @@ bool MasterConnectionManager::ConnectImpl( |
LOG(ERROR) << "Connect() from process " << process_identifier |
<< " for connection ID " << connection_id.ToString() |
<< " which is not pending"; |
- return false; |
+ return Result::FAILURE; |
} |
PendingConnectionInfo* info = it->second; |
@@ -443,23 +476,27 @@ bool MasterConnectionManager::ConnectImpl( |
LOG(ERROR) << "Connect() from process " << process_identifier |
<< " for connection ID " << connection_id.ToString() |
<< " which is neither connectee"; |
- return false; |
+ return Result::FAILURE; |
} |
+ // TODO(vtl): FIXME -- add stuff for SUCCESS_CONNECT_REUSE_CONNECTION here. |
+ Result result = Result::FAILURE; |
if (info->first == info->second) { |
platform_handle->reset(); |
DCHECK(!info->remaining_handle.is_valid()); |
+ result = Result::SUCCESS_CONNECT_SAME_PROCESS; |
} else { |
embedder::PlatformChannelPair platform_channel_pair; |
*platform_handle = platform_channel_pair.PassServerHandle(); |
DCHECK(platform_handle->is_valid()); |
info->remaining_handle = platform_channel_pair.PassClientHandle(); |
DCHECK(info->remaining_handle.is_valid()); |
+ result = Result::SUCCESS_CONNECT_NEW_CONNECTION; |
} |
DVLOG(1) << "Connection ID " << connection_id.ToString() |
<< ": first Connect() from process identifier " |
<< process_identifier; |
- return true; |
+ return result; |
} |
ProcessIdentifier remaining_connectee; |
@@ -479,7 +516,7 @@ bool MasterConnectionManager::ConnectImpl( |
<< " in state " << info->state; |
pending_connections_.erase(it); |
delete info; |
- return false; |
+ return Result::FAILURE; |
} |
if (process_identifier != remaining_connectee) { |
@@ -488,18 +525,28 @@ bool MasterConnectionManager::ConnectImpl( |
<< " which is not the remaining connectee"; |
pending_connections_.erase(it); |
delete info; |
- return false; |
+ return Result::FAILURE; |
} |
*peer_process_identifier = peer; |
- *platform_handle = info->remaining_handle.Pass(); |
- DCHECK((info->first == info->second) ^ platform_handle->is_valid()); |
+ |
+ // TODO(vtl): FIXME -- add stuff for SUCCESS_CONNECT_REUSE_CONNECTION here. |
+ Result result = Result::FAILURE; |
+ if (info->first == info->second) { |
+ platform_handle->reset(); |
+ DCHECK(!info->remaining_handle.is_valid()); |
+ result = Result::SUCCESS_CONNECT_SAME_PROCESS; |
+ } else { |
+ *platform_handle = info->remaining_handle.Pass(); |
+ DCHECK(platform_handle->is_valid()); |
+ result = Result::SUCCESS_CONNECT_NEW_CONNECTION; |
+ } |
pending_connections_.erase(it); |
delete info; |
DVLOG(1) << "Connection ID " << connection_id.ToString() |
<< ": second Connect() from process identifier " |
<< process_identifier; |
- return true; |
+ return result; |
} |
void MasterConnectionManager::ShutdownOnPrivateThread() { |
@@ -555,7 +602,7 @@ void MasterConnectionManager::OnError(ProcessIdentifier process_identifier) { |
delete helper; |
{ |
- base::AutoLock locker(lock_); |
+ MutexLocker locker(&mutex_); |
// TODO(vtl): This isn't very efficient. |
for (auto it = pending_connections_.begin(); |