BlockingUDPTransport wrap close() to break ref. loop
This commit is contained in:
@@ -16,6 +16,22 @@
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace {
|
||||
struct closer {
|
||||
epics::pvAccess::Transport::shared_pointer P;
|
||||
closer(const epics::pvAccess::Transport::shared_pointer& P) :P(P) {}
|
||||
void operator()(epics::pvAccess::Transport*) {
|
||||
try{
|
||||
P->close();
|
||||
}catch(...){
|
||||
P.reset();
|
||||
throw;
|
||||
}
|
||||
P.reset();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
@@ -72,7 +88,10 @@ Transport::shared_pointer BlockingUDPConnector::connect(TransportClient::shared_
|
||||
BlockingUDPTransport::shared_pointer transport(new BlockingUDPTransport(_serverFlag, responseHandler,
|
||||
socket, bindAddress, transportRevision));
|
||||
|
||||
return Transport::shared_pointer(transport);
|
||||
// the worker thread holds a strong ref, which is released by transport->close()
|
||||
Transport::shared_pointer ret(transport.get(), closer(transport));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
class BlockingUDPConnector;
|
||||
|
||||
enum InetAddressType { inetAddressType_all, inetAddressType_unicast, inetAddressType_broadcast_multicast };
|
||||
|
||||
class BlockingUDPTransport : public epics::pvData::NoDefaultMethods,
|
||||
@@ -46,10 +48,13 @@ class BlockingUDPTransport : public epics::pvData::NoDefaultMethods,
|
||||
public:
|
||||
POINTER_DEFINITIONS(BlockingUDPTransport);
|
||||
|
||||
private:
|
||||
friend class BlockingUDPConnector;
|
||||
BlockingUDPTransport(bool serverFlag,
|
||||
ResponseHandler::shared_pointer const & responseHandler,
|
||||
SOCKET channel, osiSockAddr &bindAddress,
|
||||
short remoteTransportRevision);
|
||||
public:
|
||||
|
||||
static shared_pointer create(bool serverFlag,
|
||||
ResponseHandler::shared_pointer const & responseHandler,
|
||||
|
||||
@@ -263,6 +263,7 @@ void ServerContextImpl::initialize()
|
||||
_timer.reset(new Timer("pvAccess-server timer", lowerPriority));
|
||||
|
||||
ServerContextImpl::shared_pointer thisServerContext = shared_from_this();
|
||||
// we create reference cycles here which are broken by our shutdown() method,
|
||||
_responseHandler.reset(new ServerResponseHandler(thisServerContext));
|
||||
|
||||
_acceptor.reset(new BlockingTCPAcceptor(thisServerContext, _responseHandler, _ifaceAddr, _receiveBufferSize));
|
||||
|
||||
Reference in New Issue
Block a user