diff --git a/.hgtags b/.hgtags index 1d77148..07a3bed 100644 --- a/.hgtags +++ b/.hgtags @@ -20,3 +20,7 @@ ceca448e7c62c23388a0c866c905c7080633a875 4.0.0 cf6fc9696904fd1735523a70a4f59b5ad6a3f2d5 4.0.0 cf6fc9696904fd1735523a70a4f59b5ad6a3f2d5 4.0.0 91b7272415af8fdb5b81c98cc6c374558d2ab805 4.0.0 +91b7272415af8fdb5b81c98cc6c374558d2ab805 4.0.0 +84ef9a50bccaf7fcd1aef1b3a5d0cd6336fdac4c 4.0.0 +84ef9a50bccaf7fcd1aef1b3a5d0cd6336fdac4c 4.0.0 +c6df866bf6ca8f9385c91dd74b65fea34bab58ca 4.0.0 diff --git a/src/remote/codec.cpp b/src/remote/codec.cpp index cffe3fe..67bb701 100644 --- a/src/remote/codec.cpp +++ b/src/remote/codec.cpp @@ -1138,6 +1138,9 @@ namespace epics { // clean resources internalClose(true); + // this is important to avoid cyclic refs (memory leak) + clearSendQueue(); + _sendQueue.wakeup(); // post close diff --git a/src/remote/codec.h b/src/remote/codec.h index 3c36f54..9bfa24f 100644 --- a/src/remote/codec.h +++ b/src/remote/codec.h @@ -168,6 +168,11 @@ namespace epics { } } + size_t size() { + epics::pvData::Lock lock(_queueMutex); + return _queue.size(); + } + private: std::deque _queue; diff --git a/testApp/remote/channelAccessIFTest.cpp b/testApp/remote/channelAccessIFTest.cpp index 740449e..7f90f0a 100755 --- a/testApp/remote/channelAccessIFTest.cpp +++ b/testApp/remote/channelAccessIFTest.cpp @@ -2119,6 +2119,12 @@ void ChannelAccessIFTest::test_stressPutAndGetLargeArray() { return; } + bool s = putReq->syncGet(getTimeoutSec()); + if (!s) { + testFail("%s: sync get failed", CURRENT_FUNCTION); + return; + } + PVDoubleArray::shared_pointer value = putReq->getPVStructure()->getSubField("value"); if (!value.get()) { testFail("%s: getting double array value field failed ", CURRENT_FUNCTION); @@ -2297,9 +2303,7 @@ void ChannelAccessIFTest::test_stressMonitorAndProcess() { return; } - while(monitorReq->getMonitorCounter() < i) { - monitorReq->waitUntilMonitor(getTimeoutSec()); - } + monitorReq->waitUntilMonitor(i, getTimeoutSec()); int counter = monitorReq->getMonitorCounter(); diff --git a/testApp/remote/syncTestRequesters.h b/testApp/remote/syncTestRequesters.h index 8a4ae56..68b1e6d 100755 --- a/testApp/remote/syncTestRequesters.h +++ b/testApp/remote/syncTestRequesters.h @@ -48,7 +48,7 @@ class SyncBaseRequester { SyncBaseRequester(bool debug = false): m_debug(debug), - m_event(new Event()), + m_event(), m_connectedStatus(false), m_getStatus(false), m_putStatus(false) {} @@ -126,25 +126,17 @@ class SyncBaseRequester { } void resetEvent() { - Lock lock(m_eventMutex); - m_event.reset(new Event()); + m_event.tryWait(); } void signalEvent() { - Lock lock(m_eventMutex); - m_event->signal(); + m_event.signal(); } bool waitUntilEvent(double timeOut) { - std::tr1::shared_ptr event; - { - Lock lock(m_eventMutex); - event = m_event; - } - - bool signaled = event->wait(timeOut); + bool signaled = m_event.wait(timeOut); if (!signaled) { if (m_debug) @@ -158,7 +150,7 @@ class SyncBaseRequester { private: - std::tr1::shared_ptr m_event; + epics::pvData::Event m_event; bool m_connectedStatus; bool m_getStatus; bool m_putStatus; @@ -167,7 +159,6 @@ class SyncBaseRequester { Mutex m_getStatusMutex; Mutex m_putStatusMutex; Mutex m_processStatusMutex; - Mutex m_eventMutex; }; @@ -1136,6 +1127,31 @@ class SyncMonitorRequesterImpl: public MonitorRequester, public SyncBaseRequeste return m_monitorStatus; } + bool waitUntilMonitor(int expectedCount, double timeOut) + { + + resetEvent(); + + { + Lock lock(m_pointerMutex); + m_monitorStatus = false; + if (m_monitorCounter >= expectedCount) + return true; + } + + + bool signaled = waitUntilEvent(timeOut); + if (!signaled) { + + if (m_debug) + std::cerr << getRequesterName() << ".waitUntilMonitor:" << " timeout occurred" << endl; + + return false; + } + + Lock lock(m_pointerMutex); + return m_monitorStatus; + } virtual string getRequesterName() {