queue.take possible race, send thread does not wait for read anymore
This commit is contained in:
@@ -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
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user