1#![feature(doc_cfg)]
2
3#![allow(clippy::missing_safety_doc)]
6
7use std::thread::JoinHandle;
11
12macro_rules! unbracket {
13 (_ [$($tt1:tt)*]) => { $($tt1)* };
14 (() [$($tt1:tt)*]) => { ($($tt1)*) };
15 ([] [$($tt1:tt)*]) => { [$($tt1)*] };
16 ({} [$($tt1:tt)*]) => { {$($tt1)*} };
17 ($tt0:tt [$($tt1:tt)*] @unbracket ($($tt2:tt)*) $($tt3:tt)*) => { unbracket!{ $tt0 [$($tt1)* $($tt2)*] $($tt3)*} };
18 ($tt0:tt [$($tt1:tt)*] @unbracket [$($tt2:tt)*] $($tt3:tt)*) => { unbracket!{ $tt0 [$($tt1)* $($tt2)*] $($tt3)*} };
19 ($tt0:tt [$($tt1:tt)*] @unbracket {$($tt2:tt)*} $($tt3:tt)*) => { unbracket!{ $tt0 [$($tt1)* $($tt2)*] $($tt3)*} };
20 ($tt0:tt [$($tt1:tt)*] $tt2:tt $($tt3:tt)*) => { unbracket!{$tt0 [$($tt1)* $tt2] $($tt3)*} };
21}
22
23macro_rules! cfg_doc {
24 ($(#[doc=$doc0:literal])+ decl: $decl:tt $($($(#[doc=$doc1:literal])+)? if $cfg:tt $body:tt)*) => {
25 unbracket! {_ []
26 #[cfg(doc)]
27 #[doc(cfg(any($($cfg),*)))]
28 $(#[doc=$doc0])+
29 $($(
30 $(#[doc=$doc1])+
31 )?)*
32 @unbracket $decl {
33 unimplemented!("Documentation implementation!");
34 }
35
36 $(
37 #[cfg(all(not(doc), $cfg))]
38 @unbracket $decl
39 $body
40 )*
41 }
42 }
43}
44
45cfg_doc! {
46 decl: [pub unsafe fn kill_thread_graceful<T>(handle: JoinHandle<T>)]
54
55 if unix {
56 use std::os::unix::thread::JoinHandleExt;
57 use libc::pthread_cancel;
58
59 let raw_handle = handle.into_pthread_t();
60 pthread_cancel(raw_handle);
61 }
62}
63
64cfg_doc! {
65 decl: [pub unsafe fn kill_thread_forcibly_exit_code<T>(handle: JoinHandle<T>, exit_code: u32)]
72
73 if windows {
74 use std::os::windows::io::IntoRawHandle;
75 use winapi::um::processthreadsapi::TerminateThread;
76 use winapi::ctypes::c_void as winapi_c_void;
77
78 let raw_handle = handle.into_raw_handle();
79 TerminateThread(raw_handle as *mut winapi_c_void, exit_code);
80 }
81}
82
83cfg_doc! {
84 decl: [pub unsafe fn suspend_thread<T>(handle: JoinHandle<T>)]
91
92 if windows {
93 use std::os::windows::io::IntoRawHandle;
94 use winapi::um::processthreadsapi::SuspendThread;
95 use winapi::ctypes::c_void as winapi_c_void;
96
97 let raw_handle = handle.into_raw_handle();
98 SuspendThread(raw_handle as *mut winapi_c_void);
99 }
100}