diff options
author | Star Rauchenberger <fefferburbia@gmail.com> | 2024-06-09 20:04:45 -0400 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2024-06-09 20:04:45 -0400 |
commit | 8c27e45ef690a58c2aa5241d76f5389ce9659435 (patch) | |
tree | 4405917726d47bd430b9731730466ba5be0c3a12 | |
parent | 23a3d0e2cd3f72455f7f23e0db2462b00940fbf0 (diff) | |
download | lingo-ap-tracker-8c27e45ef690a58c2aa5241d76f5389ce9659435.tar.gz lingo-ap-tracker-8c27e45ef690a58c2aa5241d76f5389ce9659435.tar.bz2 lingo-ap-tracker-8c27e45ef690a58c2aa5241d76f5389ce9659435.zip |
Fixed suspected thread synchronization issue
-rw-r--r-- | src/ap_state.cpp | 49 | ||||
-rw-r--r-- | src/tracker_state.cpp | 17 |
2 files changed, 42 insertions, 24 deletions
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 { | |||
151 | sunwarp_shuffle = false; | 151 | sunwarp_shuffle = false; |
152 | sunwarp_mapping.clear(); | 152 | sunwarp_mapping.clear(); |
153 | 153 | ||
154 | std::mutex connection_mutex; | ||
154 | connected = false; | 155 | connected = false; |
155 | has_connection_result = false; | 156 | has_connection_result = false; |
156 | 157 | ||
@@ -218,7 +219,7 @@ struct APState { | |||
218 | RefreshTracker(false); | 219 | RefreshTracker(false); |
219 | }); | 220 | }); |
220 | 221 | ||
221 | apclient->set_slot_connected_handler([this]( | 222 | apclient->set_slot_connected_handler([this, &connection_mutex]( |
222 | const nlohmann::json& slot_data) { | 223 | const nlohmann::json& slot_data) { |
223 | tracker_frame->SetStatusMessage("Connected to Archipelago!"); | 224 | tracker_frame->SetStatusMessage("Connected to Archipelago!"); |
224 | wxLogStatus("Connected to Archipelago!"); | 225 | wxLogStatus("Connected to Archipelago!"); |
@@ -271,12 +272,6 @@ struct APState { | |||
271 | } | 272 | } |
272 | } | 273 | } |
273 | 274 | ||
274 | connected = true; | ||
275 | has_connection_result = true; | ||
276 | |||
277 | ResetReachabilityRequirements(); | ||
278 | RefreshTracker(true); | ||
279 | |||
280 | std::list<std::string> corrected_keys; | 275 | std::list<std::string> corrected_keys; |
281 | for (const std::string& key : tracked_data_storage_keys) { | 276 | for (const std::string& key : tracked_data_storage_keys) { |
282 | corrected_keys.push_back(data_storage_prefix + key); | 277 | corrected_keys.push_back(data_storage_prefix + key); |
@@ -293,12 +288,23 @@ struct APState { | |||
293 | 288 | ||
294 | apclient->Get(corrected_keys); | 289 | apclient->Get(corrected_keys); |
295 | apclient->SetNotify(corrected_keys); | 290 | apclient->SetNotify(corrected_keys); |
291 | |||
292 | { | ||
293 | std::lock_guard connection_lock(connection_mutex); | ||
294 | if (!has_connection_result) { | ||
295 | connected = true; | ||
296 | has_connection_result = true; | ||
297 | } | ||
298 | } | ||
296 | }); | 299 | }); |
297 | 300 | ||
298 | apclient->set_slot_refused_handler( | 301 | apclient->set_slot_refused_handler( |
299 | [this](const std::list<std::string>& errors) { | 302 | [this, &connection_mutex](const std::list<std::string>& errors) { |
300 | connected = false; | 303 | { |
301 | has_connection_result = true; | 304 | std::lock_guard connection_lock(connection_mutex); |
305 | connected = false; | ||
306 | has_connection_result = true; | ||
307 | } | ||
302 | 308 | ||
303 | tracker_frame->SetStatusMessage("Disconnected from Archipelago."); | 309 | tracker_frame->SetStatusMessage("Disconnected from Archipelago."); |
304 | 310 | ||
@@ -337,17 +343,29 @@ struct APState { | |||
337 | int timeout = 5000; // 5 seconds | 343 | int timeout = 5000; // 5 seconds |
338 | int interval = 100; | 344 | int interval = 100; |
339 | int remaining_loops = timeout / interval; | 345 | int remaining_loops = timeout / interval; |
340 | while (!has_connection_result) { | 346 | while (true) { |
341 | if (interval == 0) { | 347 | { |
342 | connected = false; | 348 | std::lock_guard connection_lock(connection_mutex); |
343 | has_connection_result = true; | 349 | if (has_connection_result) { |
350 | break; | ||
351 | } | ||
352 | } | ||
344 | 353 | ||
354 | if (interval == 0) { | ||
345 | DestroyClient(); | 355 | DestroyClient(); |
346 | 356 | ||
347 | tracker_frame->SetStatusMessage("Disconnected from Archipelago."); | 357 | tracker_frame->SetStatusMessage("Disconnected from Archipelago."); |
348 | wxLogStatus("Timeout while connecting to Archipelago server."); | 358 | wxLogStatus("Timeout while connecting to Archipelago server."); |
349 | wxMessageBox("Timeout while connecting to Archipelago server.", | 359 | wxMessageBox("Timeout while connecting to Archipelago server.", |
350 | "Connection failed", wxOK | wxICON_ERROR); | 360 | "Connection failed", wxOK | wxICON_ERROR); |
361 | |||
362 | { | ||
363 | std::lock_guard connection_lock(connection_mutex); | ||
364 | connected = false; | ||
365 | has_connection_result = true; | ||
366 | } | ||
367 | |||
368 | break; | ||
351 | } | 369 | } |
352 | 370 | ||
353 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); | 371 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); |
@@ -356,7 +374,8 @@ struct APState { | |||
356 | } | 374 | } |
357 | 375 | ||
358 | if (connected) { | 376 | if (connected) { |
359 | RefreshTracker(false); | 377 | ResetReachabilityRequirements(); |
378 | RefreshTracker(true); | ||
360 | } else { | 379 | } else { |
361 | client_active = false; | 380 | client_active = false; |
362 | } | 381 | } |
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() { | |||
584 | } | 584 | } |
585 | 585 | ||
586 | void RecalculateReachability() { | 586 | void RecalculateReachability() { |
587 | std::lock_guard reachability_guard(GetState().reachability_mutex); | ||
588 | |||
587 | StateCalculator state_calculator({.start = GD_GetRoomByName("Menu")}); | 589 | StateCalculator state_calculator({.start = GD_GetRoomByName("Menu")}); |
588 | state_calculator.Calculate(); | 590 | state_calculator.Calculate(); |
589 | 591 | ||
@@ -616,14 +618,11 @@ void RecalculateReachability() { | |||
616 | std::set<int> reachable_paintings = state_calculator.GetReachablePaintings(); | 618 | std::set<int> reachable_paintings = state_calculator.GetReachablePaintings(); |
617 | std::map<int, std::map<std::string, bool>> door_reports = | 619 | std::map<int, std::map<std::string, bool>> door_reports = |
618 | state_calculator.GetDoorReports(); | 620 | state_calculator.GetDoorReports(); |
619 | 621 | ||
620 | { | 622 | std::swap(GetState().reachability, new_reachability); |
621 | std::lock_guard reachability_guard(GetState().reachability_mutex); | 623 | std::swap(GetState().reachable_doors, new_reachable_doors); |
622 | std::swap(GetState().reachability, new_reachability); | 624 | std::swap(GetState().reachable_paintings, reachable_paintings); |
623 | std::swap(GetState().reachable_doors, new_reachable_doors); | 625 | std::swap(GetState().door_reports, door_reports); |
624 | std::swap(GetState().reachable_paintings, reachable_paintings); | ||
625 | std::swap(GetState().door_reports, door_reports); | ||
626 | } | ||
627 | } | 626 | } |
628 | 627 | ||
629 | bool IsLocationReachable(int location_id) { | 628 | bool IsLocationReachable(int location_id) { |
@@ -651,5 +650,5 @@ bool IsPaintingReachable(int painting_id) { | |||
651 | const std::map<std::string, bool>& GetDoorRequirements(int door_id) { | 650 | const std::map<std::string, bool>& GetDoorRequirements(int door_id) { |
652 | std::lock_guard reachability_guard(GetState().reachability_mutex); | 651 | std::lock_guard reachability_guard(GetState().reachability_mutex); |
653 | 652 | ||
654 | return GetState().door_reports[door_id]; | 653 | return GetState().door_reports.at(door_id); |
655 | } | 654 | } |