From 9e090fa19152d9c13f1d09cdd99b32829d4f9895 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 4 Apr 2018 10:02:21 -0700 Subject: [PATCH] client context: avoid lock order violations avoid ordering violation of calling checkAndGetTransport(), which locks channel mutex, while request mutex is locked. --- src/remoteClient/clientContextImpl.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/remoteClient/clientContextImpl.cpp b/src/remoteClient/clientContextImpl.cpp index 14c2547..4050bcc 100644 --- a/src/remoteClient/clientContextImpl.cpp +++ b/src/remoteClient/clientContextImpl.cpp @@ -2057,14 +2057,18 @@ public: if (sendAck) { + guard.unlock(); + try { m_channel->checkAndGetTransport()->enqueueSendRequest(shared_from_this()); } catch (std::runtime_error&) { // assume wrong connection state from checkAndGetTransport() + guard.lock(); m_reportQueueStateInProgress = false; } catch (std::exception& e) { LOG(logLevelWarn, "Ignore exception during MonitorStrategyQueue::release: %s", e.what()); + guard.lock(); m_reportQueueStateInProgress = false; } } @@ -2389,12 +2393,19 @@ public: if (!startRequest(QOS_PROCESS | QOS_GET)) return BaseRequestImpl::otherRequestPendingStatus; + bool restore = m_started; + m_started = true; + + guard.unlock(); + try { m_channel->checkAndGetTransport()->enqueueSendRequest(internal_from_this()); - m_started = true; return Status::Ok; } catch (std::runtime_error &rte) { + guard.lock(); + + m_started = restore; abortRequest(); return BaseRequestImpl::channelNotConnected; } @@ -2415,12 +2426,19 @@ public: if (!startRequest(QOS_PROCESS)) return BaseRequestImpl::otherRequestPendingStatus; + bool restore = m_started; + m_started = false; + + guard.unlock(); + try { m_channel->checkAndGetTransport()->enqueueSendRequest(internal_from_this()); - m_started = false; return Status::Ok; } catch (std::runtime_error &rte) { + guard.lock(); + + m_started = restore; abortRequest(); return BaseRequestImpl::channelNotConnected; }