From 4fe8a118ccae2d9715b0fff38bbd129332efbd36 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 23 Aug 2020 22:45:50 +0100 Subject: [PATCH] Traffic: Improve iterator robustness Attempting to fix Sentry crash FLIGHTGEAR-B, crash on shutdown. Not sure this is quite right, but the logic is clearer and we handle invalid iterators better. --- src/ATC/trafficcontrol.cxx | 42 +++++++++++++++++--------------------- src/ATC/trafficcontrol.hxx | 9 +++++--- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/ATC/trafficcontrol.cxx b/src/ATC/trafficcontrol.cxx index 363585bcd..2b8eca56e 100644 --- a/src/ATC/trafficcontrol.cxx +++ b/src/ATC/trafficcontrol.cxx @@ -1046,33 +1046,29 @@ void FGTowerController::signOff(int id) { // Search activeTraffic for a record matching our id TrafficVectorIterator i = searchActiveTraffic(activeTraffic, id); - - // If this aircraft has left the runway, we can clear the departure record for this runway - ActiveRunwayVecIterator rwy = activeRunways.begin(); - if (! activeRunways.empty()) { - //while ((rwy->getRunwayName() != i->getRunway()) && (rwy != activeRunways.end())) { - while (rwy != activeRunways.end()) { - if (rwy->getRunwayName() == i->getRunway()) { - break; - } - rwy++; - } - if (rwy != activeRunways.end()) { - rwy->setCleared(0); - rwy->updatedepartureQueue(); - } else { - SG_LOG(SG_ATC, SG_ALERT, - "AI error: Attempting to erase non-existing runway clearance record in FGTowerController::signoff at " << SG_ORIGIN); - } - } if (i == activeTraffic.end() || (activeTraffic.empty())) { SG_LOG(SG_ATC, SG_ALERT, "AI error: Aircraft without traffic record is signing off from tower at " << SG_ORIGIN); - } else { - i->getAircraft()->resetTakeOffStatus(); - i = activeTraffic.erase(i); - SG_LOG(SG_ATC, SG_DEBUG, "Signing off from tower controller"); + return; } + + const auto trafficRunway = i->getRunway(); + auto runwayIt = std::find_if(activeRunways.begin(), activeRunways.end(), + [&trafficRunway](const ActiveRunway& ar) { + return ar.getRunwayName() == trafficRunway; + }); + + if (runwayIt != activeRunways.end()) { + runwayIt->setCleared(0); + runwayIt->updatedepartureQueue(); + } else { + SG_LOG(SG_ATC, SG_ALERT, + "AI error: Attempting to erase non-existing runway clearance record in FGTowerController::signoff at " << SG_ORIGIN); + } + + i->getAircraft()->resetTakeOffStatus(); + activeTraffic.erase(i); + SG_LOG(SG_ATC, SG_DEBUG, "Signing off from tower controller"); } // NOTE: diff --git a/src/ATC/trafficcontrol.hxx b/src/ATC/trafficcontrol.hxx index 3e7163979..b1979a224 100644 --- a/src/ATC/trafficcontrol.hxx +++ b/src/ATC/trafficcontrol.hxx @@ -331,13 +331,16 @@ public: distanceToFinal = 6.0 * SG_NM_TO_METER; }; - std::string getRunwayName() { + const std::string& getRunwayName() const + { return rwy; }; - int getCleared () { + int getCleared() const + { return currentlyCleared; }; - double getApproachDistance() { + const double getApproachDistance() const + { return distanceToFinal; }; //time_t getEstApproachTime() { return estimatedArrival; };