2424#include < set>
2525#include < span>
2626#include < sstream>
27+ #include < stop_token>
2728#include < string>
2829#include < string_view>
2930#include < system_error>
@@ -1271,15 +1272,15 @@ namespace lvh::detail {
12711272
12721273 void start_repeat_thread (std::uint32_t interval_ms) {
12731274 repeat_running_ = true ;
1274- repeat_thread_ = std::thread {[this , interval_ms]() {
1275- while (repeat_running_) {
1275+ repeat_thread_ = std::jthread {[this , interval_ms](std::stop_token stop_token ) {
1276+ while (!stop_token. stop_requested () && repeat_running_) {
12761277 std::this_thread::sleep_for (std::chrono::milliseconds {interval_ms});
1277- if (!repeat_running_ || !is_open ()) {
1278+ if (stop_token. stop_requested () || !repeat_running_ || !is_open ()) {
12781279 break ;
12791280 }
12801281
12811282 for (const auto key_code : pressed_keys_snapshot ()) {
1282- if (!repeat_running_ || !is_open ()) {
1283+ if (stop_token. stop_requested () || !repeat_running_ || !is_open ()) {
12831284 break ;
12841285 }
12851286 static_cast <void >(emit_keyboard_event ({.key_code = key_code, .pressed = true }));
@@ -1291,13 +1292,14 @@ namespace lvh::detail {
12911292 void stop_repeat_thread () {
12921293 repeat_running_ = false ;
12931294 if (repeat_thread_.joinable ()) {
1295+ repeat_thread_.request_stop ();
12941296 repeat_thread_.join ();
12951297 }
12961298 }
12971299
12981300 std::string device_name_;
12991301 std::atomic_bool repeat_running_ = false ;
1300- std::thread repeat_thread_;
1302+ std::jthread repeat_thread_;
13011303 mutable std::mutex pressed_keys_mutex_;
13021304 std::set<KeyboardKeyCode> pressed_keys_;
13031305 };
@@ -2196,12 +2198,12 @@ namespace lvh::detail {
21962198 }
21972199
21982200 running_ = true ;
2199- reader_ = std::thread {[this ]() {
2200- read_loop ();
2201+ reader_ = std::jthread {[this ](std::stop_token stop_token ) {
2202+ read_loop (stop_token );
22012203 }};
22022204 if (profile_.gamepad_kind == GamepadProfileKind::dualsense) {
2203- periodic_reporter_ = std::thread {[this ]() {
2204- periodic_report_loop ();
2205+ periodic_reporter_ = std::jthread {[this ](std::stop_token stop_token ) {
2206+ periodic_report_loop (stop_token );
22052207 }};
22062208 }
22072209 return OperationStatus::success ();
@@ -2243,6 +2245,12 @@ namespace lvh::detail {
22432245 }
22442246
22452247 running_ = false ;
2248+ if (periodic_reporter_.joinable ()) {
2249+ periodic_reporter_.request_stop ();
2250+ }
2251+ if (reader_.joinable ()) {
2252+ reader_.request_stop ();
2253+ }
22462254
22472255 auto status = OperationStatus::success ();
22482256 if (fd_ >= 0 ) {
@@ -2288,8 +2296,8 @@ namespace lvh::detail {
22882296 return OperationStatus::success ();
22892297 }
22902298
2291- void read_loop () {
2292- while (running_) {
2299+ void read_loop (std::stop_token stop_token ) {
2300+ while (!stop_token. stop_requested () && running_) {
22932301 pollfd descriptor {};
22942302 descriptor.fd = fd_;
22952303 descriptor.events = POLLIN ;
@@ -2344,10 +2352,10 @@ namespace lvh::detail {
23442352 }
23452353 }
23462354
2347- void periodic_report_loop () {
2348- while (running_) {
2355+ void periodic_report_loop (std::stop_token stop_token ) {
2356+ while (!stop_token. stop_requested () && running_) {
23492357 std::this_thread::sleep_for (std::chrono::milliseconds {dualsense_periodic_report_ms});
2350- if (!running_ || !open_) {
2358+ if (stop_token. stop_requested () || !running_ || !open_) {
23512359 break ;
23522360 }
23532361
@@ -2442,8 +2450,8 @@ namespace lvh::detail {
24422450 std::vector<std::uint8_t > last_report_;
24432451 std::atomic_bool open_ = true ;
24442452 std::atomic_bool running_ = false ;
2445- std::thread reader_;
2446- std::thread periodic_reporter_;
2453+ std::jthread reader_;
2454+ std::jthread periodic_reporter_;
24472455 std::mutex write_mutex_;
24482456 std::mutex report_mutex_;
24492457 std::mutex callback_mutex_;
0 commit comments