about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2024-06-09 20:04:45 -0400
committerStar Rauchenberger <fefferburbia@gmail.com>2024-06-09 20:04:45 -0400
commit8c27e45ef690a58c2aa5241d76f5389ce9659435 (patch)
tree4405917726d47bd430b9731730466ba5be0c3a12
parent23a3d0e2cd3f72455f7f23e0db2462b00940fbf0 (diff)
downloadlingo-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.cpp49
-rw-r--r--src/tracker_state.cpp17
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
586void RecalculateReachability() { 586void 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
629bool IsLocationReachable(int location_id) { 628bool IsLocationReachable(int location_id) {
@@ -651,5 +650,5 @@ bool IsPaintingReachable(int painting_id) {
651const std::map<std::string, bool>& GetDoorRequirements(int door_id) { 650const 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}