queue.take possible race, send thread does not wait for read anymore

This commit is contained in:
Matej Sekoranja
2015-01-07 12:58:28 +01:00
parent ffeab62d7f
commit 228d7fe279
3 changed files with 17 additions and 4 deletions
+4 -3
View File
@@ -1214,7 +1214,7 @@ namespace epics {
void BlockingAbstractCodec::sendThread(void *param)
{
BlockingAbstractCodec *bac = static_cast<BlockingAbstractCodec *>(param);
BlockingAbstractCodec *bac = static_cast<BlockingAbstractCodec *>(param);
Transport::shared_pointer ptr = bac->shared_from_this();
bac->setSenderThread();
@@ -1241,16 +1241,17 @@ namespace epics {
}
}
/*
// wait read thread to die
// TODO rewise
// TODO rewise if this is really needed
// this timeout is needed where close() is initiated from the send thread,
// and not from the read thread as usualy - recv() does not exit until socket is not destroyed,
// which is done the internalDestroy() call below
bac->_shutdownEvent.wait(3.0);
*/
// call internal destroy
bac->internalDestroy();
}
+4 -1
View File
@@ -71,6 +71,7 @@ namespace epics {
};
// TODO replace this queue with lock-free implementation
template<typename T>
class queue {
public:
@@ -119,6 +120,7 @@ namespace epics {
}
// TODO very sub-optimal (locks and empty() - pop() sequence; at least 2 locks!)
T take(int timeOut)
{
while (true)
@@ -161,6 +163,8 @@ namespace epics {
else
{
epics::pvData::Lock lock(_queueMutex);
if (_queue.empty())
return T();
T sender = _queue.front();
_queue.pop_front();
return sender;
@@ -179,7 +183,6 @@ namespace epics {
epics::pvData::Event _queueEvent;
epics::pvData::Mutex _queueMutex;
AtomicValue<bool> _wakeup;
epics::pvData::Mutex _stdMutex;
};
+9
View File
@@ -4515,6 +4515,15 @@ TODO
// stop UDPs
m_searchTransport->close();
m_broadcastTransport->close();
// wait for all transports to cleanly exit
int tries = 40;
epics::pvData::int32 transportCount;
while ((transportCount = m_transportRegistry->numberOfActiveTransports()) && tries--)
epicsThreadSleep(0.025);
if (transportCount)
LOG(logLevelDebug, "PVA client context destroyed with %d transport(s) active.", transportCount);
}
void destroyAllChannels() {