From 07712cc1f7cbbe867b1b33ae054cb24fffe7c8ed Mon Sep 17 00:00:00 2001 From: miha_vitorovic Date: Fri, 7 Jan 2011 13:29:00 +0100 Subject: [PATCH] Fixed a crash in client which happened if a server closed connection. --- .../remote/blockingClientTCPTransport.cpp | 1 + pvAccessApp/remote/blockingTCP.h | 2 ++ pvAccessApp/remote/blockingTCPTransport.cpp | 33 +++++++++++-------- testApp/remote/testBlockingTCPClnt.cpp | 8 +++-- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/pvAccessApp/remote/blockingClientTCPTransport.cpp b/pvAccessApp/remote/blockingClientTCPTransport.cpp index 27fe8b6..a18f7a5 100644 --- a/pvAccessApp/remote/blockingClientTCPTransport.cpp +++ b/pvAccessApp/remote/blockingClientTCPTransport.cpp @@ -39,6 +39,7 @@ namespace epics { *1000), _unresponsiveTransport(false), _timerNode( new TimerNode(this)), _mutex(new Mutex()), _ownersMutex( new Mutex()), _verifyOrEcho(true) { + _autoDelete = false; // initialize owners list, send queue acquire(client); diff --git a/pvAccessApp/remote/blockingTCP.h b/pvAccessApp/remote/blockingTCP.h index 52f9b2a..5e4a20d 100644 --- a/pvAccessApp/remote/blockingTCP.h +++ b/pvAccessApp/remote/blockingTCP.h @@ -237,6 +237,8 @@ namespace epics { volatile int64 _remoteBufferFreeSpace; + volatile bool _autoDelete; + virtual void processReadCached(bool nestedCall, ReceiveStage inStage, int requiredBytes, bool addToBuffer); diff --git a/pvAccessApp/remote/blockingTCPTransport.cpp b/pvAccessApp/remote/blockingTCPTransport.cpp index 0f60846..113cd48 100644 --- a/pvAccessApp/remote/blockingTCPTransport.cpp +++ b/pvAccessApp/remote/blockingTCPTransport.cpp @@ -72,17 +72,18 @@ namespace epics { _priority(priority), _responseHandler(responseHandler), _totalBytesReceived(0), _totalBytesSent(0), _markerToSend(0), _verified(false), _remoteBufferFreeSpace( - LONG_LONG_MAX), _markerPeriodBytes(MARKER_PERIOD), - _nextMarkerPosition(_markerPeriodBytes), - _sendPending(false), _lastMessageStartPosition(0), _mutex( - new Mutex()), _sendQueueMutex(new Mutex()), - _verifiedMutex(new Mutex()), _monitorMutex(new Mutex()), - _stage(READ_FROM_SOCKET), _lastSegmentedMessageType(0), - _lastSegmentedMessageCommand(0), _storedPayloadSize(0), - _storedPosition(0), _storedLimit(0), _magicAndVersion(0), - _packetType(0), _command(0), _payloadSize(0), - _flushRequested(false), _sendBufferSentPosition(0), - _flushStrategy(DELAYED), _sendQueue( + LONG_LONG_MAX), _autoDelete(true), + _markerPeriodBytes(MARKER_PERIOD), _nextMarkerPosition( + _markerPeriodBytes), _sendPending(false), + _lastMessageStartPosition(0), _mutex(new Mutex()), + _sendQueueMutex(new Mutex()), _verifiedMutex(new Mutex()), + _monitorMutex(new Mutex()), _stage(READ_FROM_SOCKET), + _lastSegmentedMessageType(0), _lastSegmentedMessageCommand( + 0), _storedPayloadSize(0), _storedPosition(0), + _storedLimit(0), _magicAndVersion(0), _packetType(0), + _command(0), _payloadSize(0), _flushRequested(false), + _sendBufferSentPosition(0), _flushStrategy(DELAYED), + _sendQueue( new GrowingCircularBuffer (100)), _rcvThreadId(NULL), _sendThreadId(NULL), _monitorSendQueue( new GrowingCircularBuffer (100)), @@ -850,10 +851,12 @@ namespace epics { obj->processReadCached(false, NONE, CA_MESSAGE_HEADER_SIZE, false); - while(obj->_sendThreadRunning) - epicsThreadSleep(0.1); + if(obj->_autoDelete) { + while(obj->_sendThreadRunning) + epicsThreadSleep(0.1); - delete obj; + delete obj; + } } void BlockingTCPTransport::sendThreadRunner(void* param) { @@ -867,12 +870,14 @@ namespace epics { } void BlockingTCPTransport::enqueueSendRequest(TransportSender* sender) { + if(_closed) return; Lock lock(_sendQueueMutex); _sendQueue->insert(sender); } void BlockingTCPTransport::enqueueMonitorSendRequest( TransportSender* sender) { + if(_closed) return; Lock lock(_monitorMutex); _monitorSendQueue->insert(sender); if(_monitorSendQueue->size()==1) enqueueSendRequest(_monitorSender); diff --git a/testApp/remote/testBlockingTCPClnt.cpp b/testApp/remote/testBlockingTCPClnt.cpp index 8218dfa..c583b74 100644 --- a/testApp/remote/testBlockingTCPClnt.cpp +++ b/testApp/remote/testBlockingTCPClnt.cpp @@ -112,8 +112,7 @@ void testBlockingTCPSender() { osiSockAddr srvAddr; - srvAddr.ia.sin_family = AF_INET; - //srvAddr.ia.sin_port = htons(CA_SERVER_PORT); + //srvAddr.ia.sin_family = AF_INET; if(aToIPAddr("192.168.71.132", CA_SERVER_PORT, &srvAddr.ia)<0) { cout<<"error in aToIPAddr(...)"<enqueueSendRequest(&dts); + if(!transport->isClosed()) + transport->enqueueSendRequest(&dts); + else + break; sleep(1); }