diff --git a/src/gui/input/InputAPIAddWindow.cpp b/src/gui/input/InputAPIAddWindow.cpp index 8783dd220..688ee14ea 100644 --- a/src/gui/input/InputAPIAddWindow.cpp +++ b/src/gui/input/InputAPIAddWindow.cpp @@ -212,7 +212,7 @@ void InputAPIAddWindow::on_api_selected(wxCommandEvent& event) void InputAPIAddWindow::on_controller_dropdown(wxCommandEvent& event) { - if (m_search_thread.joinable()) + if (m_search_running) return; int selection = m_input_api->GetSelection(); @@ -238,31 +238,38 @@ void InputAPIAddWindow::on_controller_dropdown(wxCommandEvent& event) // TODO selected_uuid } + m_search_running = true; + wxWindowUpdateLocker lock(m_controller_list); m_controller_list->Clear(); m_controller_list->Append(_("Searching for controllers..."), (wxClientData*)nullptr); m_controller_list->SetSelection(wxNOT_FOUND); - m_search_thread = std::jthread([this, provider, selected_uuid](std::stop_token stopToken) + m_search_thread_data = std::make_unique(); + std::thread([this, provider, selected_uuid](std::shared_ptr data) { auto available_controllers = provider->get_controllers(); - if(!stopToken.stop_requested()) { - wxCommandEvent event(wxControllersRefreshed); - event.SetEventObject(m_controller_list); - event.SetClientObject(new wxCustomData(std::move(available_controllers))); - event.SetInt(provider->api()); - event.SetString(selected_uuid); - wxPostEvent(this, event); + std::lock_guard lock{data->mutex}; + if(!data->discardResult) + { + wxCommandEvent event(wxControllersRefreshed); + event.SetEventObject(m_controller_list); + event.SetClientObject(new wxCustomData(std::move(available_controllers))); + event.SetInt(provider->api()); + event.SetString(selected_uuid); + wxPostEvent(this, event); + m_search_running = false; + } } - }); + }, m_search_thread_data).detach(); } void InputAPIAddWindow::on_controller_selected(wxCommandEvent& event) { - if (m_search_thread.joinable()) + if (m_search_running) { return; } @@ -282,7 +289,6 @@ void InputAPIAddWindow::on_controller_selected(wxCommandEvent& event) void InputAPIAddWindow::on_controllers_refreshed(wxCommandEvent& event) { - m_search_thread = {}; const auto type = event.GetInt(); wxASSERT(0 <= type && type < InputAPI::MAX); @@ -311,10 +317,10 @@ void InputAPIAddWindow::on_controllers_refreshed(wxCommandEvent& event) void InputAPIAddWindow::discard_thread_result() { - if(m_search_thread.joinable()) + m_search_running = false; + if(m_search_thread_data) { - m_search_thread.request_stop(); - m_search_thread.detach(); - m_search_thread = {}; + std::lock_guard lock{m_search_thread_data->mutex}; + m_search_thread_data->discardResult = true; } } diff --git a/src/gui/input/InputAPIAddWindow.h b/src/gui/input/InputAPIAddWindow.h index 807fe9721..085dd6239 100644 --- a/src/gui/input/InputAPIAddWindow.h +++ b/src/gui/input/InputAPIAddWindow.h @@ -52,5 +52,11 @@ class InputAPIAddWindow : public wxDialog std::shared_ptr m_controller; std::vector m_controllers; - std::jthread m_search_thread; + std::atomic_bool m_search_running = false; + struct AsyncThreadData + { + std::atomic_bool discardResult = false; + std::mutex mutex; + }; + std::shared_ptr m_search_thread_data; };