Purge read and write queues after a close succeeds

pull/4/head
Paul Hollinsky 2018-11-16 18:48:28 -05:00
parent 82adbcaba6
commit 8a147e2c3f
4 changed files with 118 additions and 71 deletions

View File

@ -99,10 +99,16 @@ bool FTDI::close() {
closing = false;
bool ret = true;
if(ftdiDevice.close())
return false;
ret = false;
return true;
uint8_t flush;
WriteOperation flushop;
while(readQueue.try_dequeue(flush)) {}
while(writeQueue.try_dequeue(flushop)) {}
return ret;
}
void FTDI::readTask() {

View File

@ -257,6 +257,11 @@ bool STM32::close() {
int ret = ::close(fd);
fd = -1;
uint8_t flush;
WriteOperation flushop;
while (readQueue.try_dequeue(flush)) {}
while (writeQueue.try_dequeue(flushop)) {}
return ret == 0;
}

View File

@ -233,6 +233,11 @@ bool PCAP::close() {
pcap.close(interface.fp);
interface.fp = nullptr;
uint8_t flush;
WriteOperation flushop;
while(readQueue.try_dequeue(flush)) {}
while(writeQueue.try_dequeue(flushop)) {}
return true;
}

View File

@ -18,9 +18,10 @@ static const std::wstring ALL_ENUM_REG_KEY = L"SYSTEM\\CurrentControlSet\\Enum\\
static constexpr unsigned int RETRY_TIMES = 5;
static constexpr unsigned int RETRY_DELAY = 50;
std::vector<neodevice_t> VCP::FindByProduct(int product, wchar_t* driverName) {
std::vector<neodevice_t> VCP::FindByProduct(int product, std::vector<std::wstring> driverNames) {
std::vector<neodevice_t> found;
for(auto& driverName : driverNames) {
std::wstringstream regss;
regss << DRIVER_SERVICES_REG_KEY << driverName << L"\\Enum\\";
std::wstring driverEnumRegKey = regss.str();
@ -64,7 +65,8 @@ std::vector<neodevice_t> VCP::FindByProduct(int product, wchar_t* driverName) {
int sn = 0;
try {
sn = std::stoi(entry.substr(startchar + 1));
} catch(...) {
}
catch(...) {
conversionError = true;
}
@ -72,11 +74,15 @@ std::vector<neodevice_t> VCP::FindByProduct(int product, wchar_t* driverName) {
if(!sn || conversionError) {
// This is a device with characters in the serial number
oss << entry.substr(startchar + 1, 6);
} else {
}
else {
oss << sn;
}
strcpy_s(device.serial, sizeof(device.serial), converter.to_bytes(oss.str()).c_str());
std::string serial = converter.to_bytes(oss.str());
if(serial.find_first_of('\\') != std::string::npos)
continue; // Not sure how this happened but a slash is not valid in the serial
strcpy_s(device.serial, sizeof(device.serial), serial.c_str());
// Serial number is saved, we want the COM port number now
// This will be stored under ALL_ENUM_REG_KEY\entry\Device Parameters\PortName (entry from the FTDI_ENUM)
@ -90,11 +96,22 @@ std::vector<neodevice_t> VCP::FindByProduct(int product, wchar_t* driverName) {
if(compos != std::wstring::npos) {
try {
device.handle = std::stoi(port.substr(compos + 3));
} catch(...) {} // In case of this, or any other error, handle has already been initialized to 0
}
catch(...) {} // In case of this, or any other error, handle has already been initialized to 0
}
bool alreadyFound = false;
for(auto& foundDev : found) {
if(foundDev.handle == device.handle && serial == foundDev.serial) {
alreadyFound = true;
break;
}
}
if(!alreadyFound)
found.push_back(device);
}
}
return found;
}
@ -113,8 +130,10 @@ bool VCP::open(bool fromAsync) {
if(isOpen() || (!fromAsync && opening))
return false;
if(!IsHandleValid(device.handle))
if(!IsHandleValid(device.handle)) {
err(APIError::DriverFailedToOpen);
return false;
}
opening = true;
@ -132,8 +151,10 @@ bool VCP::open(bool fromAsync) {
opening = false;
if(!isOpen())
if(!isOpen()) {
err(APIError::DriverFailedToOpen);
return false;
}
// Set the timeouts
COMMTIMEOUTS timeouts;
@ -151,6 +172,7 @@ bool VCP::open(bool fromAsync) {
if(!SetCommTimeouts(handle, &timeouts)) {
close();
err(APIError::DriverFailedToOpen);
return false;
}
@ -158,6 +180,7 @@ bool VCP::open(bool fromAsync) {
DCB comstate;
if(!GetCommState(handle, &comstate)) {
close();
err(APIError::DriverFailedToOpen);
return false;
}
@ -170,6 +193,7 @@ bool VCP::open(bool fromAsync) {
if(!SetCommState(handle, &comstate)) {
close();
err(APIError::DriverFailedToOpen);
return false;
}
@ -181,12 +205,14 @@ bool VCP::open(bool fromAsync) {
overlappedWait.hEvent = CreateEvent(nullptr, true, false, nullptr);
if (overlappedRead.hEvent == nullptr || overlappedWrite.hEvent == nullptr || overlappedWait.hEvent == nullptr) {
close();
err(APIError::DriverFailedToOpen);
return false;
}
// Set up event so that we will satisfy overlappedWait when a character comes in
if(!SetCommMask(handle, EV_RXCHAR)) {
close();
err(APIError::DriverFailedToOpen);
return false;
}
@ -238,6 +264,11 @@ bool VCP::close() {
overlappedWait.hEvent = INVALID_HANDLE_VALUE;
}
uint8_t flush;
WriteOperation flushop;
while(readQueue.try_dequeue(flush)) {}
while(writeQueue.try_dequeue(flushop)) {}
// TODO Set up some sort of shared memory, free which COM port we had open so we can try to open it again
return ret;