summaryrefslogtreecommitdiff
path: root/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc')
-rw-r--r--src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc53
1 files changed, 40 insertions, 13 deletions
diff --git a/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc b/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
index fcae508747..36f6dd98d0 100644
--- a/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
+++ b/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
@@ -242,11 +242,9 @@ TransportAdapter::Error TransportAdapterImpl::Connect(
const TransportAdapter::Error err =
server_connection_factory_->CreateConnection(device_id, app_handle);
if (TransportAdapter::OK != err) {
- connections_lock_.AcquireForWriting();
if (!pending_app) {
- connections_.erase(std::make_pair(device_id, app_handle));
+ RemoveConnection(device_id, app_handle);
}
- connections_lock_.Release();
}
LOG4CXX_TRACE(logger_, "exit with error: " << err);
return err;
@@ -719,14 +717,12 @@ void TransportAdapterImpl::DeviceDisconnected(
listener->OnDisconnectDeviceDone(this, device_uid);
}
- connections_lock_.AcquireForWriting();
for (ApplicationList::const_iterator i = app_list.begin();
i != app_list.end();
++i) {
ApplicationHandle app_handle = *i;
- connections_.erase(std::make_pair(device_uid, app_handle));
+ RemoveConnection(device_uid, app_handle);
}
- connections_lock_.Release();
RemoveDevice(device_uid);
LOG4CXX_TRACE(logger_, "exit");
@@ -776,9 +772,7 @@ void TransportAdapterImpl::DisconnectDone(const DeviceUID& device_handle,
listener->OnDisconnectDeviceDone(this, device_uid);
}
}
- connections_lock_.AcquireForWriting();
- connections_.erase(std::make_pair(device_uid, app_uid));
- connections_lock_.Release();
+ RemoveConnection(device_uid, app_uid);
if (device_disconnected) {
RemoveDevice(device_uid);
@@ -973,9 +967,7 @@ void TransportAdapterImpl::ConnectFailed(const DeviceUID& device_handle,
LOG4CXX_TRACE(logger_,
"enter. device_id: " << &device_uid << ", app_handle: "
<< &app_uid << ", error: " << &error);
- connections_lock_.AcquireForWriting();
- connections_.erase(std::make_pair(device_uid, app_uid));
- connections_lock_.Release();
+ RemoveConnection(device_uid, app_uid);
for (TransportAdapterListenerList::iterator it = listeners_.begin();
it != listeners_.end();
++it) {
@@ -989,12 +981,13 @@ void TransportAdapterImpl::RemoveFinalizedConnection(
const DeviceUID device_uid = device_handle;
LOG4CXX_AUTO_TRACE(logger_);
{
- sync_primitives::AutoWriteLock lock(connections_lock_);
+ connections_lock_.AcquireForWriting();
auto it_conn = connections_.find(std::make_pair(device_uid, app_handle));
if (connections_.end() == it_conn) {
LOG4CXX_WARN(logger_,
"Device_id: " << &device_uid << ", app_handle: "
<< &app_handle << " connection not found");
+ connections_lock_.Release();
return;
}
const ConnectionInfo& info = it_conn->second;
@@ -1002,9 +995,21 @@ void TransportAdapterImpl::RemoveFinalizedConnection(
LOG4CXX_WARN(logger_,
"Device_id: " << &device_uid << ", app_handle: "
<< &app_handle << " connection not finalized");
+ connections_lock_.Release();
return;
}
+ // By copying the info.connection shared pointer into this local variable,
+ // we can delay the connection's destructor until after
+ // connections_lock_.Release.
+ LOG4CXX_DEBUG(
+ logger_,
+ "RemoveFinalizedConnection copying connection with Device_id: "
+ << &device_uid << ", app_handle: " << &app_handle);
+ ConnectionSPtr connection = info.connection;
connections_.erase(it_conn);
+ connections_lock_.Release();
+ LOG4CXX_DEBUG(logger_,
+ "RemoveFinalizedConnection Connections Lock Released");
}
DeviceSptr device = FindDevice(device_handle);
@@ -1019,6 +1024,28 @@ void TransportAdapterImpl::RemoveFinalizedConnection(
}
}
+void TransportAdapterImpl::RemoveConnection(
+ const DeviceUID& device_id, const ApplicationHandle& app_handle) {
+ ConnectionSPtr connection;
+ connections_lock_.AcquireForWriting();
+ ConnectionMap::const_iterator it =
+ connections_.find(std::make_pair(device_id, app_handle));
+ if (it != connections_.end()) {
+ // By copying the connection from the map to this shared pointer,
+ // we can erase the object from the map without triggering the destructor
+ LOG4CXX_DEBUG(logger_,
+ "Copying connection with Device_id: "
+ << &device_id << ", app_handle: " << &app_handle);
+ connection = it->second.connection;
+ connections_.erase(it);
+ }
+ connections_lock_.Release();
+ LOG4CXX_DEBUG(logger_, "Connections Lock Released");
+
+ // And now, "connection" goes out of scope, triggering the destructor outside
+ // of the "connections_lock_"
+}
+
void TransportAdapterImpl::AddListener(TransportAdapterListener* listener) {
LOG4CXX_TRACE(logger_, "enter");
listeners_.push_back(listener);