From ab54697745164a37792f87f8c406f88da7c53c43 Mon Sep 17 00:00:00 2001 From: Kyle Schwarz Date: Fri, 15 Jul 2022 16:03:54 -0400 Subject: [PATCH] Device: Retain Device objects between FindAll() calls FindAll() now retains a list of Devices that have already been created and returns their existing object instead of a new one. --- device/devicefinder.cpp | 108 +++++++++++++++++++++++++++------------- 1 file changed, 73 insertions(+), 35 deletions(-) diff --git a/device/devicefinder.cpp b/device/devicefinder.cpp index efa020a..1679955 100644 --- a/device/devicefinder.cpp +++ b/device/devicefinder.cpp @@ -40,135 +40,173 @@ static void makeIfPIDMatches(const FoundDevice& dev, std::vector> DeviceFinder::FindAll() { - static std::vector driverFoundDevices; - driverFoundDevices.clear(); + static std::vector newDriverFoundDevices; + newDriverFoundDevices.clear(); #ifdef ICSNEO_ENABLE_FIRMIO - FirmIO::Find(driverFoundDevices); + FirmIO::Find(newDriverFoundDevices); #endif #ifdef ICSNEO_ENABLE_RAW_ETHERNET - PCAP::Find(driverFoundDevices); + PCAP::Find(newDriverFoundDevices); #endif #ifdef ICSNEO_ENABLE_CDCACM - CDCACM::Find(driverFoundDevices); + CDCACM::Find(newDriverFoundDevices); #endif #ifdef ICSNEO_ENABLE_FTDI - FTDI::Find(driverFoundDevices); + FTDI::Find(newDriverFoundDevices); #endif - std::vector> foundDevices; + // Weak because we don't want to keep devices open if they go out of scope elsewhere + static std::vector> foundDevices; + // Remove Devices that have dropped out of scope or are no longer present + for (auto it = foundDevices.begin(); it != foundDevices.end(); ) { + if (const auto device = it->lock()) { + if (std::none_of(newDriverFoundDevices.begin(), newDriverFoundDevices.end(), + [&](const auto& driverDevice) { + return std::string(driverDevice.serial) == device->getSerial(); + } + )) { + it = foundDevices.erase(it); // Device not found by drivers but pointer has a >0 use_count, error? + } else { + ++it; // Valid weak pointer and device found by drivers + } + } else { + it = foundDevices.erase(it); // Weak pointer has a zero use_count + } + } + + // Remove existing driver devices so we only create new ones + for (auto it = newDriverFoundDevices.begin(); it != newDriverFoundDevices.end(); ) { + if (std::any_of(foundDevices.begin(), foundDevices.end(), + [&](const auto& weakDevice) { + const auto device = weakDevice.lock(); + return device && std::string(it->serial) == device->getSerial(); + } + )) { + it = newDriverFoundDevices.erase(it); + } else { + ++it; + } + } + + std::vector> newFoundDevices; + newFoundDevices.reserve(newDriverFoundDevices.size()); // Offer found devices to each of the subclasses - for (const FoundDevice& dev : driverFoundDevices) { + for (const FoundDevice& dev : newDriverFoundDevices) { #ifdef __ETHERBADGE_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __NEOOBD2PRO_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __NEOOBD2SIM_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __NEOVIFIRE_H_ - makeIfPIDMatches(dev, foundDevices); + makeIfPIDMatches(dev, newFoundDevices); #endif #ifdef __NEOVIFIRE2_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __NEOVIRED2_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __NEOVIION_H_ - makeIfPIDMatches(dev, foundDevices); + makeIfPIDMatches(dev, newFoundDevices); #endif #ifdef __NEOVIPLASMA_H_ - makeIfPIDMatches(dev, foundDevices); + makeIfPIDMatches(dev, newFoundDevices); #endif #ifdef __RADEPSILON_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __RADGALAXY_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __RADMARS_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __RADGIGASTAR_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __RADJUPITER_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __RADMOON2_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __RADMOONDUO_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __RADPLUTO_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __RADSTAR2_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __RADSUPERMOON_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __VALUECAN3_H_ - makeIfPIDMatches(dev, foundDevices); + makeIfPIDMatches(dev, newFoundDevices); #endif #ifdef __VALUECAN4_1_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __VALUECAN4_2_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __VALUECAN4_2EL_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __VALUECAN4_4_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __VALUECAN4INDUSTRIAL_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __VIVIDCAN_H_ - makeIfSerialMatches(dev, foundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif } - for(auto& device : foundDevices) { + for(auto& device : newFoundDevices) { AddBuiltInExtensionsTo(device); } - return foundDevices; + // Grab a weak pointer from the new devices + foundDevices.insert(foundDevices.end(), newFoundDevices.begin(), newFoundDevices.end()); + + // Upgrade to shared for the return + return std::vector>(foundDevices.begin(), foundDevices.end()); } const std::vector& DeviceFinder::GetSupportedDevices() {