From 8c27e45ef690a58c2aa5241d76f5389ce9659435 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Sun, 9 Jun 2024 20:04:45 -0400 Subject: Fixed suspected thread synchronization issue --- src/ap_state.cpp | 49 ++++++++++++++++++++++++++++++++++--------------- src/tracker_state.cpp | 17 ++++++++--------- 2 files changed, 42 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/ap_state.cpp b/src/ap_state.cpp index 0ce4582..8ff0ccd 100644 --- a/src/ap_state.cpp +++ b/src/ap_state.cpp @@ -151,6 +151,7 @@ struct APState { sunwarp_shuffle = false; sunwarp_mapping.clear(); + std::mutex connection_mutex; connected = false; has_connection_result = false; @@ -218,7 +219,7 @@ struct APState { RefreshTracker(false); }); - apclient->set_slot_connected_handler([this]( + apclient->set_slot_connected_handler([this, &connection_mutex]( const nlohmann::json& slot_data) { tracker_frame->SetStatusMessage("Connected to Archipelago!"); wxLogStatus("Connected to Archipelago!"); @@ -271,12 +272,6 @@ struct APState { } } - connected = true; - has_connection_result = true; - - ResetReachabilityRequirements(); - RefreshTracker(true); - std::list corrected_keys; for (const std::string& key : tracked_data_storage_keys) { corrected_keys.push_back(data_storage_prefix + key); @@ -293,12 +288,23 @@ struct APState { apclient->Get(corrected_keys); apclient->SetNotify(corrected_keys); + + { + std::lock_guard connection_lock(connection_mutex); + if (!has_connection_result) { + connected = true; + has_connection_result = true; + } + } }); apclient->set_slot_refused_handler( - [this](const std::list& errors) { - connected = false; - has_connection_result = true; + [this, &connection_mutex](const std::list& errors) { + { + std::lock_guard connection_lock(connection_mutex); + connected = false; + has_connection_result = true; + } tracker_frame->SetStatusMessage("Disconnected from Archipelago."); @@ -337,17 +343,29 @@ struct APState { int timeout = 5000; // 5 seconds int interval = 100; int remaining_loops = timeout / interval; - while (!has_connection_result) { - if (interval == 0) { - connected = false; - has_connection_result = true; + while (true) { + { + std::lock_guard connection_lock(connection_mutex); + if (has_connection_result) { + break; + } + } + if (interval == 0) { DestroyClient(); tracker_frame->SetStatusMessage("Disconnected from Archipelago."); wxLogStatus("Timeout while connecting to Archipelago server."); wxMessageBox("Timeout while connecting to Archipelago server.", "Connection failed", wxOK | wxICON_ERROR); + + { + std::lock_guard connection_lock(connection_mutex); + connected = false; + has_connection_result = true; + } + + break; } std::this_thread::sleep_for(std::chrono::milliseconds(100)); @@ -356,7 +374,8 @@ struct APState { } if (connected) { - RefreshTracker(false); + ResetReachabilityRequirements(); + RefreshTracker(true); } else { client_active = false; } diff --git a/src/tracker_state.cpp b/src/tracker_state.cpp index 66e7751..a4134f9 100644 --- a/src/tracker_state.cpp +++ b/src/tracker_state.cpp @@ -584,6 +584,8 @@ void ResetReachabilityRequirements() { } void RecalculateReachability() { + std::lock_guard reachability_guard(GetState().reachability_mutex); + StateCalculator state_calculator({.start = GD_GetRoomByName("Menu")}); state_calculator.Calculate(); @@ -616,14 +618,11 @@ void RecalculateReachability() { std::set reachable_paintings = state_calculator.GetReachablePaintings(); std::map> door_reports = state_calculator.GetDoorReports(); - - { - std::lock_guard reachability_guard(GetState().reachability_mutex); - std::swap(GetState().reachability, new_reachability); - std::swap(GetState().reachable_doors, new_reachable_doors); - std::swap(GetState().reachable_paintings, reachable_paintings); - std::swap(GetState().door_reports, door_reports); - } + + std::swap(GetState().reachability, new_reachability); + std::swap(GetState().reachable_doors, new_reachable_doors); + std::swap(GetState().reachable_paintings, reachable_paintings); + std::swap(GetState().door_reports, door_reports); } bool IsLocationReachable(int location_id) { @@ -651,5 +650,5 @@ bool IsPaintingReachable(int painting_id) { const std::map& GetDoorRequirements(int door_id) { std::lock_guard reachability_guard(GetState().reachability_mutex); - return GetState().door_reports[door_id]; + return GetState().door_reports.at(door_id); } -- cgit 1.4.1