diff --git a/src/ca/caChannel.cpp b/src/ca/caChannel.cpp index 7d2dc09..47b4fe3 100644 --- a/src/ca/caChannel.cpp +++ b/src/ca/caChannel.cpp @@ -137,7 +137,9 @@ void CAChannel::activate(short priority) CAChannel::~CAChannel() { if(DEBUG_LEVEL>0) { - cout << "CAChannel::~CAChannel() " << channelName << endl; + cout << "CAChannel::~CAChannel() " << channelName + << " channelCreated " << (channelCreated ? "true" : "false") + << endl; } { Lock lock(requestsMutex); @@ -725,7 +727,8 @@ CAChannelMonitor::~CAChannelMonitor() << endl; } if(isStarted) stop(); - stopMonitorThread->waitForNoEvents(); + stopMonitorThread->addNoEventsCallback(&waitForNoEvents); + waitForNoEvents.wait(); } void CAChannelMonitor::activate() @@ -800,6 +803,7 @@ epics::pvData::Status CAChannelMonitor::start() } channel->attachContext(); monitorQueue->start(); + isStarted = true; int result = ca_create_subscription(dbdToPv->getRequestType(), 0, channel->getChannelID(), DBE_VALUE, @@ -807,7 +811,6 @@ epics::pvData::Status CAChannelMonitor::start() &eventID); if (result == ECA_NORMAL) { - isStarted = true; result = ca_flush_io(); } if (result == ECA_NORMAL) return status; diff --git a/src/ca/caChannel.h b/src/ca/caChannel.h index 529d17d..24b0dfd 100644 --- a/src/ca/caChannel.h +++ b/src/ca/caChannel.h @@ -219,6 +219,7 @@ private: StopMonitorThreadPtr stopMonitorThread; DbdToPvPtr dbdToPv; + epics::pvData::Event waitForNoEvents; epics::pvData::PVStructure::shared_pointer pvStructure; epics::pvData::MonitorElementPtr activeElement; evid eventID; diff --git a/src/ca/caProviderPvt.h b/src/ca/caProviderPvt.h index 3ba1cab..c04361e 100644 --- a/src/ca/caProviderPvt.h +++ b/src/ca/caProviderPvt.h @@ -17,7 +17,7 @@ namespace epics { namespace pvAccess { namespace ca { -#define DEBUG_LEVEL 1 +#define DEBUG_LEVEL 0 class StopMonitorThread; typedef std::tr1::shared_ptr StopMonitorThreadPtr; diff --git a/src/ca/stopMonitorThread.cpp b/src/ca/stopMonitorThread.cpp index ab1c356..794bcd6 100644 --- a/src/ca/stopMonitorThread.cpp +++ b/src/ca/stopMonitorThread.cpp @@ -34,7 +34,6 @@ StopMonitorThreadPtr StopMonitorThread::get() StopMonitorThread::StopMonitorThread() : isStop(false), isAttachContext(false), - isWaitForNoEvents(false), current_context(NULL) { } @@ -74,27 +73,19 @@ void StopMonitorThread::stop() void StopMonitorThread::callStop(evid pevid) { - { - Lock xx(mutex); - evidQueue.push(&(*pevid)); - } + Lock xx(mutex); + evidQueue.push(&(*pevid)); waitForCommand.signal(); } -void StopMonitorThread::waitForNoEvents() +void StopMonitorThread::addNoEventsCallback(Event * event) { - while(true) - { - { - Lock xx(mutex); - if(evidQueue.size()==0) return; - isWaitForNoEvents = true; - } - waitForCommand.signal(); - noMoreEvents.wait(); - } + Lock xx(mutex); + noEventsCallbackQueue.push(event); + waitForCommand.signal(); } + void StopMonitorThread::run() { while(true) @@ -112,7 +103,7 @@ void StopMonitorThread::run() isAttachContext = false; } if(evidQueue.size()>0) - { + { while(!evidQueue.empty()) { evid pvid = evidQueue.front(); @@ -125,10 +116,14 @@ void StopMonitorThread::run() } } } - if(isWaitForNoEvents) + if(noEventsCallbackQueue.size()>0) { - isWaitForNoEvents = false; - noMoreEvents.signal(); + while(!noEventsCallbackQueue.empty()) + { + Event * event = noEventsCallbackQueue.front(); + noEventsCallbackQueue.pop(); + event->signal(); + } } if(isStop) { waitForStop.signal(); diff --git a/src/ca/stopMonitorThread.h b/src/ca/stopMonitorThread.h index 4b88627..d2e7bd2 100644 --- a/src/ca/stopMonitorThread.h +++ b/src/ca/stopMonitorThread.h @@ -20,9 +20,11 @@ namespace epics { namespace pvAccess { namespace ca { + class StopMonitorThread; typedef std::tr1::shared_ptr StopMonitorThreadPtr; + class StopMonitorThread : public epicsThreadRunable { @@ -34,7 +36,7 @@ public: static StopMonitorThreadPtr get(); void callStop(evid pevid); void attachContext(ca_client_context* current_context); - void waitForNoEvents(); + void addNoEventsCallback(epics::pvData::Event * event); private: StopMonitorThread(); @@ -42,11 +44,10 @@ private: epics::pvData::Mutex mutex; epics::pvData::Event waitForCommand; epics::pvData::Event waitForStop; - epics::pvData::Event noMoreEvents; std::queue evidQueue; + std::queue noEventsCallbackQueue; bool isStop; bool isAttachContext; - bool isWaitForNoEvents; ca_client_context* current_context; };