From 7e0e181772e31e13024c5dea4c1094ffd155c002 Mon Sep 17 00:00:00 2001 From: Andrew Stitcher Date: Wed, 8 Sep 2010 16:49:37 +0000 Subject: Only delete Rdma server side connections when the client disconnects - this avoids a race between the disconnect event and deleting the connection upon closing. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@995141 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpid/sys/RdmaIOPlugin.cpp | 24 ++++++++++++------------ cpp/src/qpid/sys/rdma/rdma_wrap.h | 4 ++++ 2 files changed, 16 insertions(+), 12 deletions(-) (limited to 'cpp/src') diff --git a/cpp/src/qpid/sys/RdmaIOPlugin.cpp b/cpp/src/qpid/sys/RdmaIOPlugin.cpp index 40967ca7c4..8c7f410f00 100644 --- a/cpp/src/qpid/sys/RdmaIOPlugin.cpp +++ b/cpp/src/qpid/sys/RdmaIOPlugin.cpp @@ -123,9 +123,6 @@ void RdmaIOHandler::write(const framing::ProtocolInitiation& data) } void RdmaIOHandler::close() { - Mutex::ScopedLock l(pollingLock); - if (!polling) return; - polling = false; aio->drainWriteQueue(boost::bind(&RdmaIOHandler::drained, this)); } @@ -167,6 +164,12 @@ void RdmaIOHandler::error(Rdma::AsynchIO&) { disconnected(); } +namespace { + void stopped(RdmaIOHandler* async) { + delete async; + } +} + void RdmaIOHandler::disconnected() { { Mutex::ScopedLock l(pollingLock); @@ -174,18 +177,13 @@ void RdmaIOHandler::disconnected() { if (!polling) return; polling = false; } - drained(); -} - -namespace { - void stopped(RdmaIOHandler* async) { - delete async; - } + aio->stop(boost::bind(&stopped, this)); } void RdmaIOHandler::drained() { - assert(!polling); - aio->stop(boost::bind(&stopped, this)); + // We know we've drained the write queue now, but we don't have to do anything + // because we can rely on the client to disconnect to trigger the connection + // cleanup. } void RdmaIOHandler::full(Rdma::AsynchIO&) { @@ -325,6 +323,8 @@ void RdmaIOProtocolFactory::disconnected(Rdma::Connection::intrusive_ptr ci) { // If we've got a connection already tear it down, otherwise ignore RdmaIOHandler* async = ci->getContext(); if (async) { + // Make sure we don't disconnect more than once + ci->removeContext(); async->disconnected(); } } diff --git a/cpp/src/qpid/sys/rdma/rdma_wrap.h b/cpp/src/qpid/sys/rdma/rdma_wrap.h index 51cf6864be..1d72abcd03 100644 --- a/cpp/src/qpid/sys/rdma/rdma_wrap.h +++ b/cpp/src/qpid/sys/rdma/rdma_wrap.h @@ -225,6 +225,10 @@ namespace Rdma { context = c; } + void removeContext() { + context = 0; + } + template T* getContext() { return static_cast(context); -- cgit v1.2.1