Communication: Fix MultiChannelCommunication race
parent
f53bc2e920
commit
fbdab1e998
|
|
@ -9,7 +9,7 @@ using namespace icsneo;
|
||||||
MultiChannelCommunication::MultiChannelCommunication(device_eventhandler_t err, std::unique_ptr<Driver> com,
|
MultiChannelCommunication::MultiChannelCommunication(device_eventhandler_t err, std::unique_ptr<Driver> com,
|
||||||
std::function<std::unique_ptr<Packetizer>()> makeConfiguredPacketizer, std::unique_ptr<Encoder> e,
|
std::function<std::unique_ptr<Packetizer>()> makeConfiguredPacketizer, std::unique_ptr<Encoder> e,
|
||||||
std::unique_ptr<Decoder> md, size_t vnetCount) :
|
std::unique_ptr<Decoder> md, size_t vnetCount) :
|
||||||
Communication(err, std::move(com), makeConfiguredPacketizer, std::move(e), std::move(md)), numVnets(vnetCount) {
|
Communication(err, std::move(com), makeConfiguredPacketizer, std::move(e), std::move(md)), numVnets(vnetCount), packetRB(2048) {
|
||||||
vnetThreads.resize(numVnets);
|
vnetThreads.resize(numVnets);
|
||||||
vnetQueues.resize(numVnets);
|
vnetQueues.resize(numVnets);
|
||||||
}
|
}
|
||||||
|
|
@ -148,9 +148,13 @@ void MultiChannelCommunication::hidReadTask() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!currentQueue->enqueue(std::move(payloadBytes)) && gotPacket)
|
{
|
||||||
|
std::unique_lock lk(ringBufMutex);
|
||||||
|
if(!packetRB.write(std::move(payloadBytes)) && gotPacket)
|
||||||
EventManager::GetInstance().add(APIEvent(APIEvent::Type::FailedToRead, APIEvent::Severity::Error));
|
EventManager::GetInstance().add(APIEvent(APIEvent::Type::FailedToRead, APIEvent::Severity::Error));
|
||||||
payloadBytes.clear();
|
payloadBytes.clear();
|
||||||
|
}
|
||||||
|
ringBufCV.notify_all();
|
||||||
gotPacket = true;
|
gotPacket = true;
|
||||||
state = PreprocessState::SearchForCommand;
|
state = PreprocessState::SearchForCommand;
|
||||||
break;
|
break;
|
||||||
|
|
@ -160,7 +164,6 @@ void MultiChannelCommunication::hidReadTask() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiChannelCommunication::vnetReadTask(size_t vnetIndex) {
|
void MultiChannelCommunication::vnetReadTask(size_t vnetIndex) {
|
||||||
moodycamel::BlockingReaderWriterQueue< std::vector<uint8_t> >& queue = vnetQueues[vnetIndex];
|
|
||||||
std::vector<uint8_t> payloadBytes;
|
std::vector<uint8_t> payloadBytes;
|
||||||
std::unique_ptr<Packetizer> packetizerLifetime;
|
std::unique_ptr<Packetizer> packetizerLifetime;
|
||||||
Packetizer* vnetPacketizer;
|
Packetizer* vnetPacketizer;
|
||||||
|
|
@ -174,14 +177,16 @@ void MultiChannelCommunication::vnetReadTask(size_t vnetIndex) {
|
||||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||||
|
|
||||||
while(!closing) {
|
while(!closing) {
|
||||||
if(queue.wait_dequeue_timed(payloadBytes, std::chrono::milliseconds(250))) {
|
std::unique_lock lk(ringBufMutex);
|
||||||
if(closing)
|
ringBufCV.wait(lk);
|
||||||
break;
|
if(vnetPacketizer->input(packetRB)) {
|
||||||
|
for(const auto& packet : vnetPacketizer->output()) {
|
||||||
|
std::shared_ptr<Message> msg;
|
||||||
|
if(!decoder->decode(msg, packet))
|
||||||
|
continue;
|
||||||
|
|
||||||
auto& ringBuffer = driver->getReadBuffer();
|
dispatchMessage(msg);
|
||||||
ringBuffer.write(payloadBytes);
|
}
|
||||||
|
|
||||||
handleInput(*vnetPacketizer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -113,6 +113,10 @@ private:
|
||||||
std::vector< moodycamel::BlockingReaderWriterQueue< std::vector<uint8_t> > > vnetQueues;
|
std::vector< moodycamel::BlockingReaderWriterQueue< std::vector<uint8_t> > > vnetQueues;
|
||||||
void hidReadTask();
|
void hidReadTask();
|
||||||
void vnetReadTask(size_t vnetIndex);
|
void vnetReadTask(size_t vnetIndex);
|
||||||
|
|
||||||
|
RingBuffer packetRB;
|
||||||
|
std::mutex ringBufMutex;
|
||||||
|
std::condition_variable ringBufCV;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue