I am implementing a multi-threaded application in C++11 which uses a thread to poll data from a QUdpSocket (QT5 framework) and another one to process the collected data .
When incoming data is detected by the socket, a ReadyRead()
signal is emitted and all datagrams are extracted from a QUdpSocket
and copied into a std::list
.
void SocketWrapper::QueuePendingDatagrams()
{
while (hasPendingDatagrams()) {
int dataSize = pendingDatagramSize();
QByteArray tmpQByte = receiveDatagram().data();
datagramList.push_back(tmpQByte); // see const_data
}
emit newDatagrams(&datagramList);
}
In another thread, the consumer is then started and retrieves the first element of the list until the list is empty.
void Worker::ProcessDatagrams(std::list<QByteArray>* pDatagramList)
{
while (pDatagramList->size() > 0) {
QByteArray tmpDatagram = pDatagramList->front();
pDatagramList->pop_front();
// Process and log the data within the datagram...
}
My question is: As I am always popping the first element and pushing after the last one, is this lock-free approach thread-safe?
I might (and will) receive more data to the socket during the data processing so both threads will end up running at the same time. To me, it seems that the only data race that might occur could overestimate DatagramList->size()
but I don't see why it would be a problem. If I continuously receive data, I believe that the whole list will be consumed anyway.