aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsnowstormxd <214507868+snowstormxd@users.noreply.github.com>2026-11-01 19:02:26 +0000
committersnowstormxd <214507868+snowstormxd@users.noreply.github.com>2026-11-02 19:36:34 +0000
commit5e7a14c057578d1c8262bec6f0e252801b071e87 (patch)
treeb0d5c1165c4709d8017e73fedb524df006003c25 /src
parent6a0d50bcca77987d27857b029f5e3f90dd3d141c (diff)
input: join calibration workers before destroying their owner
The detached worker could use complete_event after its owner was destroyed. Retain and join it after signaling stop. Bind the test server to loopback on Windows and verify capture release across 32 cancellations. Assisted-by: Codex (implementation, review and automated validation) (cherry picked from commit 0eb7b4855f499838d056a0d5d678109318517e9d)
Diffstat (limited to 'src')
-rw-r--r--src/input_common/drivers/udp_client.cpp4
-rw-r--r--src/input_common/drivers/udp_client.h1
-rw-r--r--src/tests/input_common/calibration_configuration_job.cpp20
3 files changed, 22 insertions, 3 deletions
diff --git a/src/input_common/drivers/udp_client.cpp b/src/input_common/drivers/udp_client.cpp
index 620e0cf630..a7840db32f 100644
--- a/src/input_common/drivers/udp_client.cpp
+++ b/src/input_common/drivers/udp_client.cpp
@@ -603,7 +603,7 @@ CalibrationConfigurationJob::CalibrationConfigurationJob(
const std::string& host, u16 port, std::function<void(Status)> status_callback,
std::function<void(u16, u16, u16, u16)> data_callback) {
- std::thread([=, this] {
+ worker = std::jthread([=, this] {
u16 min_x{UINT16_MAX};
u16 min_y{UINT16_MAX};
u16 max_x{};
@@ -647,7 +647,7 @@ CalibrationConfigurationJob::CalibrationConfigurationJob(
complete_event.Wait();
socket.Stop();
worker_thread.join();
- }).detach();
+ });
}
CalibrationConfigurationJob::~CalibrationConfigurationJob() {
diff --git a/src/input_common/drivers/udp_client.h b/src/input_common/drivers/udp_client.h
index cea9f579ac..eac3df07aa 100644
--- a/src/input_common/drivers/udp_client.h
+++ b/src/input_common/drivers/udp_client.h
@@ -183,6 +183,7 @@ public:
private:
Common::Event complete_event;
+ std::jthread worker;
};
void TestCommunication(const std::string& host, u16 port,
diff --git a/src/tests/input_common/calibration_configuration_job.cpp b/src/tests/input_common/calibration_configuration_job.cpp
index 6ded0dfc86..c45ef157a5 100644
--- a/src/tests/input_common/calibration_configuration_job.cpp
+++ b/src/tests/input_common/calibration_configuration_job.cpp
@@ -5,6 +5,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <array>
+#include <memory>
#include <string>
#include <thread>
#include <utility>
@@ -19,7 +20,7 @@
class FakeCemuhookServer {
public:
FakeCemuhookServer()
- : socket(io_context, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)) {}
+ : socket(io_context, boost::asio::ip::udp::endpoint(boost::asio::ip::address_v4::loopback(), 0)) {}
~FakeCemuhookServer() {
boost::system::error_code error_code;
@@ -132,3 +133,20 @@ TEST_CASE("CalibrationConfigurationJob completed", "[input_common]") {
REQUIRE(max_x == 200);
REQUIRE(max_y == 200);
}
+
+TEST_CASE("CalibrationConfigurationJob cancellation joins its worker", "[input_common]") {
+ FakeCemuhookServer server;
+ for (unsigned i = 0; i < 32; ++i) {
+ auto lifetime = std::make_shared<int>(0);
+ std::weak_ptr<int> observer = lifetime;
+ {
+ InputCommon::CemuhookUDP::CalibrationConfigurationJob job(
+ server.GetHost(), server.GetPort(),
+ [lifetime](InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status) {},
+ [](u16, u16, u16, u16) {});
+ lifetime.reset();
+ job.Stop();
+ }
+ REQUIRE(observer.expired());
+ }
+}