Driver: Block between read attempts

Driver:

* Refactored to limit accessibility of member fields;

Communication:

* readTask() now calls for a blocking wait;
This commit is contained in:
Kurt Wachowski
2024-08-13 13:55:12 +00:00
committed by Kyle Schwarz
parent f25a0a4a81
commit 75af3220b0
20 changed files with 116 additions and 104 deletions
+9 -11
View File
@@ -117,7 +117,7 @@ bool CDCACM::close() {
return false;
}
closing = true;
setIsClosing(true);
if(readThread.joinable())
readThread.join();
@@ -125,8 +125,8 @@ bool CDCACM::close() {
if(writeThread.joinable())
writeThread.join();
closing = false;
disconnected = false;
setIsClosing(false);
setIsDisconnected(false);
if(modeChanging) {
// We're expecting this inode to go away after we close the device
@@ -140,9 +140,7 @@ bool CDCACM::close() {
int ret = ::close(fd);
fd = -1;
WriteOperation flushop;
readBuffer.clear();
while (writeQueue.try_dequeue(flushop)) {}
clearBuffers();
if(modeChanging) {
modeChanging = false;
@@ -173,7 +171,7 @@ void CDCACM::readTask() {
constexpr size_t READ_BUFFER_SIZE = 2048;
uint8_t readbuf[READ_BUFFER_SIZE];
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while(!closing && !isDisconnected()) {
while(!isClosing() && !isDisconnected()) {
fd_set rfds = {0};
struct timeval tv = {0};
FD_SET(fd, &rfds);
@@ -199,8 +197,8 @@ void CDCACM::readTask() {
// Requesting thread is responsible for calling close. This allows for more flexibility
});
break;
} else if(!closing && !fdIsValid() && !isDisconnected()) {
disconnected = true;
} else if(!isClosing() && !fdIsValid() && !isDisconnected()) {
setIsDisconnected(true);
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
}
}
@@ -210,7 +208,7 @@ void CDCACM::readTask() {
void CDCACM::writeTask() {
WriteOperation writeOp;
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while(!closing && !isDisconnected()) {
while(!isClosing() && !isDisconnected()) {
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
continue;
@@ -233,7 +231,7 @@ void CDCACM::writeTask() {
} else if (actualWritten < 0) {
if(!fdIsValid()) {
if(!isDisconnected()) {
disconnected = true;
setIsDisconnected(true);
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
}
} else
+5 -5
View File
@@ -166,13 +166,13 @@ bool FirmIO::close() {
return false;
}
closing = true;
setIsClosing(true);
if(readThread.joinable())
readThread.join();
closing = false;
disconnected = false;
setIsClosing(false);
setIsDisconnected(false);
int ret = 0;
if(vbase != nullptr) {
@@ -202,7 +202,7 @@ void FirmIO::readTask() {
std::cerr << "FirmIO::readTask setpriority failed : " << strerror(errno) << std::endl;
}
while(!closing && !isDisconnected()) {
while(!isClosing() && !isDisconnected()) {
fd_set rfds = {0};
struct timeval tv = {0};
FD_SET(fd, &rfds);
@@ -244,7 +244,7 @@ void FirmIO::readTask() {
uint8_t* addr = reinterpret_cast<uint8_t*>(msg.payload.data.addr - PHY_ADDR_BASE + vbase);
while (!pushRx(addr, msg.payload.data.len)) {
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // back-off so reading thread can empty the buffer
if (closing || isDisconnected()) {
if (isClosing() || isDisconnected()) {
break;
}
}
+9 -11
View File
@@ -81,7 +81,7 @@ bool FTDI::open() {
ftdi.flush();
// Create threads
closing = false;
setIsClosing(false);
readThread = std::thread(&FTDI::readTask, this);
writeThread = std::thread(&FTDI::writeTask, this);
@@ -94,7 +94,7 @@ bool FTDI::close() {
return false;
}
closing = true;
setIsClosing(true);
if(readThread.joinable())
readThread.join();
@@ -109,12 +109,10 @@ bool FTDI::close() {
report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error);
}
WriteOperation flushop;
readBuffer.clear();
while(writeQueue.try_dequeue(flushop)) {}
clearBuffers();
closing = false;
disconnected = false;
setIsClosing(false);
setIsDisconnected(false);
return ret;
}
@@ -202,12 +200,12 @@ void FTDI::readTask() {
constexpr size_t READ_BUFFER_SIZE = 8;
uint8_t readbuf[READ_BUFFER_SIZE];
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while(!closing && !isDisconnected()) {
while(!isClosing() && !isDisconnected()) {
auto readBytes = ftdi.read(readbuf, READ_BUFFER_SIZE);
if(readBytes < 0) {
if(ErrorIsDisconnection(readBytes)) {
if(!isDisconnected()) {
disconnected = true;
setIsDisconnected(true);
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
}
} else
@@ -220,7 +218,7 @@ void FTDI::readTask() {
void FTDI::writeTask() {
WriteOperation writeOp;
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while(!closing && !isDisconnected()) {
while(!isClosing() && !isDisconnected()) {
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
continue;
@@ -230,7 +228,7 @@ void FTDI::writeTask() {
if(writeBytes < 0) {
if(ErrorIsDisconnection(writeBytes)) {
if(!isDisconnected()) {
disconnected = true;
setIsDisconnected(true);
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
}
break;
+5 -7
View File
@@ -258,28 +258,26 @@ bool PCAP::close() {
if(!isOpen())
return false;
closing = true; // Signal the threads that we are closing
setIsClosing(true); // Signal the threads that we are closing
pcap_breakloop(iface.fp);
#ifndef __linux__
pthread_cancel(readThread.native_handle());
#endif
readThread.join();
writeThread.join();
closing = false;
setIsClosing(false);
pcap_close(iface.fp);
iface.fp = nullptr;
WriteOperation flushop;
readBuffer.clear();
while(writeQueue.try_dequeue(flushop)) {}
clearBuffers();
return true;
}
void PCAP::readTask() {
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while (!closing) {
while (!isClosing()) {
pcap_dispatch(iface.fp, -1, [](uint8_t* obj, const struct pcap_pkthdr* header, const uint8_t* data) {
PCAP* driver = reinterpret_cast<PCAP*>(obj);
if(driver->ethPacketizer.inputUp({data, data + header->caplen})) {
@@ -294,7 +292,7 @@ void PCAP::writeTask() {
WriteOperation writeOp;
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while(!closing) {
while(!isClosing()) {
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
continue;