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; closing = false;
bool ret = true;
if(ftdiDevice.close()) 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() { void FTDI::readTask() {

View File

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

View File

@ -233,6 +233,11 @@ bool PCAP::close() {
pcap.close(interface.fp); pcap.close(interface.fp);
interface.fp = nullptr; interface.fp = nullptr;
uint8_t flush;
WriteOperation flushop;
while(readQueue.try_dequeue(flush)) {}
while(writeQueue.try_dequeue(flushop)) {}
return true; 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_TIMES = 5;
static constexpr unsigned int RETRY_DELAY = 50; 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; std::vector<neodevice_t> found;
for(auto& driverName : driverNames) {
std::wstringstream regss; std::wstringstream regss;
regss << DRIVER_SERVICES_REG_KEY << driverName << L"\\Enum\\"; regss << DRIVER_SERVICES_REG_KEY << driverName << L"\\Enum\\";
std::wstring driverEnumRegKey = regss.str(); std::wstring driverEnumRegKey = regss.str();
@ -64,7 +65,8 @@ std::vector<neodevice_t> VCP::FindByProduct(int product, wchar_t* driverName) {
int sn = 0; int sn = 0;
try { try {
sn = std::stoi(entry.substr(startchar + 1)); sn = std::stoi(entry.substr(startchar + 1));
} catch(...) { }
catch(...) {
conversionError = true; conversionError = true;
} }
@ -72,11 +74,15 @@ std::vector<neodevice_t> VCP::FindByProduct(int product, wchar_t* driverName) {
if(!sn || conversionError) { if(!sn || conversionError) {
// This is a device with characters in the serial number // This is a device with characters in the serial number
oss << entry.substr(startchar + 1, 6); oss << entry.substr(startchar + 1, 6);
} else { }
else {
oss << sn; 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 // 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) // 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) { if(compos != std::wstring::npos) {
try { try {
device.handle = std::stoi(port.substr(compos + 3)); 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); found.push_back(device);
} }
}
return found; return found;
} }
@ -113,8 +130,10 @@ bool VCP::open(bool fromAsync) {
if(isOpen() || (!fromAsync && opening)) if(isOpen() || (!fromAsync && opening))
return false; return false;
if(!IsHandleValid(device.handle)) if(!IsHandleValid(device.handle)) {
err(APIError::DriverFailedToOpen);
return false; return false;
}
opening = true; opening = true;
@ -132,8 +151,10 @@ bool VCP::open(bool fromAsync) {
opening = false; opening = false;
if(!isOpen()) if(!isOpen()) {
err(APIError::DriverFailedToOpen);
return false; return false;
}
// Set the timeouts // Set the timeouts
COMMTIMEOUTS timeouts; COMMTIMEOUTS timeouts;
@ -151,6 +172,7 @@ bool VCP::open(bool fromAsync) {
if(!SetCommTimeouts(handle, &timeouts)) { if(!SetCommTimeouts(handle, &timeouts)) {
close(); close();
err(APIError::DriverFailedToOpen);
return false; return false;
} }
@ -158,6 +180,7 @@ bool VCP::open(bool fromAsync) {
DCB comstate; DCB comstate;
if(!GetCommState(handle, &comstate)) { if(!GetCommState(handle, &comstate)) {
close(); close();
err(APIError::DriverFailedToOpen);
return false; return false;
} }
@ -170,6 +193,7 @@ bool VCP::open(bool fromAsync) {
if(!SetCommState(handle, &comstate)) { if(!SetCommState(handle, &comstate)) {
close(); close();
err(APIError::DriverFailedToOpen);
return false; return false;
} }
@ -181,12 +205,14 @@ bool VCP::open(bool fromAsync) {
overlappedWait.hEvent = CreateEvent(nullptr, true, false, nullptr); overlappedWait.hEvent = CreateEvent(nullptr, true, false, nullptr);
if (overlappedRead.hEvent == nullptr || overlappedWrite.hEvent == nullptr || overlappedWait.hEvent == nullptr) { if (overlappedRead.hEvent == nullptr || overlappedWrite.hEvent == nullptr || overlappedWait.hEvent == nullptr) {
close(); close();
err(APIError::DriverFailedToOpen);
return false; return false;
} }
// Set up event so that we will satisfy overlappedWait when a character comes in // Set up event so that we will satisfy overlappedWait when a character comes in
if(!SetCommMask(handle, EV_RXCHAR)) { if(!SetCommMask(handle, EV_RXCHAR)) {
close(); close();
err(APIError::DriverFailedToOpen);
return false; return false;
} }
@ -238,6 +264,11 @@ bool VCP::close() {
overlappedWait.hEvent = INVALID_HANDLE_VALUE; 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 // 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; return ret;