44//! the windows threads, and this module provides
55//! better control over those.
66
7- use winapi:: ctypes:: c_int;
8- use winapi:: shared:: minwindef:: DWORD ;
9- use winapi:: um:: errhandlingapi:: GetLastError ;
10- use winapi:: um:: processthreadsapi:: {
11- GetCurrentThread , GetThreadPriority , SetThreadIdealProcessor , SetThreadPriority ,
12- SetThreadPriorityBoost ,
7+ use windows:: Win32 :: {
8+ Foundation :: { GetLastError , HANDLE } ,
9+ System :: {
10+ Threading :: {
11+ GetCurrentThread , GetThreadPriority , SetThreadIdealProcessor , SetThreadPriority ,
12+ SetThreadPriorityBoost , THREAD_MODE_BACKGROUND_BEGIN , THREAD_MODE_BACKGROUND_END ,
13+ THREAD_PRIORITY , THREAD_PRIORITY_ABOVE_NORMAL , THREAD_PRIORITY_BELOW_NORMAL ,
14+ THREAD_PRIORITY_HIGHEST , THREAD_PRIORITY_IDLE , THREAD_PRIORITY_LOWEST ,
15+ THREAD_PRIORITY_NORMAL , THREAD_PRIORITY_TIME_CRITICAL ,
16+ } ,
17+ WindowsProgramming :: THREAD_PRIORITY_ERROR_RETURN ,
18+ } ,
1319} ;
14- use winapi:: um:: winbase;
15- use winapi:: um:: winnt:: HANDLE ;
1620
1721use crate :: { Error , ThreadPriority } ;
1822
1923/// An alias type for specifying the ideal processor.
2024/// Used in the WinAPI for affinity control.
21- pub type IdealProcessor = DWORD ;
25+ pub type IdealProcessor = u32 ;
2226
2327/// An alias type for a thread id.
24- pub type ThreadId = HANDLE ;
28+ #[ derive( Debug , Copy , Clone , Eq , PartialEq ) ]
29+ #[ repr( transparent) ]
30+ pub struct ThreadId ( HANDLE ) ;
31+
32+ impl PartialOrd for ThreadId {
33+ fn partial_cmp ( & self , other : & Self ) -> Option < std:: cmp:: Ordering > {
34+ Some ( self . cmp ( other) )
35+ }
36+ }
37+
38+ impl Ord for ThreadId {
39+ fn cmp ( & self , other : & Self ) -> std:: cmp:: Ordering {
40+ ( self . 0 . 0 as usize ) . cmp ( & ( other. 0 . 0 as usize ) )
41+ }
42+ }
43+
44+ impl ThreadId {
45+ /// Returns true if the thread id is invalid.
46+ pub fn is_invalid ( & self ) -> bool {
47+ self . 0 . is_invalid ( )
48+ }
49+ }
2550
2651/// The WinAPI priority representation. Check out MSDN for more info:
2752/// <https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadpriority>
28- #[ repr( u32 ) ]
53+ #[ repr( i32 ) ]
2954#[ derive( Debug , Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
3055pub enum WinAPIThreadPriority {
3156 /// Begin background processing mode. The system lowers the resource
@@ -37,7 +62,7 @@ pub enum WinAPIThreadPriority {
3762 ///
3863 /// # Warning
3964 /// Windows Server 2003: This value is not supported.
40- BackgroundModeBegin = winbase :: THREAD_MODE_BACKGROUND_BEGIN ,
65+ BackgroundModeBegin = THREAD_MODE_BACKGROUND_BEGIN . 0 ,
4166 /// End background processing mode. The system restores the resource
4267 /// scheduling priorities of the thread as they were before the thread
4368 /// entered background processing mode.
@@ -47,25 +72,25 @@ pub enum WinAPIThreadPriority {
4772 ///
4873 /// # Warning
4974 /// Windows Server 2003: This value is not supported.
50- BackgroundModeEnd = winbase :: THREAD_MODE_BACKGROUND_END ,
75+ BackgroundModeEnd = THREAD_MODE_BACKGROUND_END . 0 ,
5176 /// Priority 1 point above the priority class.
52- AboveNormal = winbase :: THREAD_PRIORITY_ABOVE_NORMAL ,
77+ AboveNormal = THREAD_PRIORITY_ABOVE_NORMAL . 0 ,
5378 /// Priority 1 point below the priority class.
54- BelowNormal = winbase :: THREAD_PRIORITY_BELOW_NORMAL ,
79+ BelowNormal = THREAD_PRIORITY_BELOW_NORMAL . 0 ,
5580 /// Priority 2 points above the priority class.
56- Highest = winbase :: THREAD_PRIORITY_HIGHEST ,
81+ Highest = THREAD_PRIORITY_HIGHEST . 0 ,
5782 /// Base priority of 1 for IDLE_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS,
5883 /// NORMAL_PRIORITY_CLASS, ABOVE_NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS
5984 /// processes, and a base priority of 16 for REALTIME_PRIORITY_CLASS processes.
60- Idle = winbase :: THREAD_PRIORITY_IDLE ,
85+ Idle = THREAD_PRIORITY_IDLE . 0 ,
6186 /// Priority 2 points below the priority class.
62- Lowest = winbase :: THREAD_PRIORITY_LOWEST ,
87+ Lowest = THREAD_PRIORITY_LOWEST . 0 ,
6388 /// Normal priority for the priority class.
64- Normal = winbase :: THREAD_PRIORITY_NORMAL ,
89+ Normal = THREAD_PRIORITY_NORMAL . 0 ,
6590 /// Base priority of 15 for IDLE_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS,
6691 /// NORMAL_PRIORITY_CLASS, ABOVE_NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS
6792 /// processes, and a base priority of 31 for REALTIME_PRIORITY_CLASS processes.
68- TimeCritical = winbase :: THREAD_PRIORITY_TIME_CRITICAL ,
93+ TimeCritical = THREAD_PRIORITY_TIME_CRITICAL . 0 ,
6994}
7095
7196impl std:: convert:: TryFrom < ThreadPriority > for WinAPIThreadPriority {
@@ -84,41 +109,43 @@ impl std::convert::TryFrom<ThreadPriority> for WinAPIThreadPriority {
84109 99 => WinAPIThreadPriority :: TimeCritical ,
85110 _ => return Err ( Error :: Priority ( "The value is out of range [0; 99]." ) ) ,
86111 } ,
87- ThreadPriority :: Os ( crate :: ThreadPriorityOsValue ( p) ) => match p {
88- winbase:: THREAD_MODE_BACKGROUND_BEGIN => WinAPIThreadPriority :: BackgroundModeBegin ,
89- winbase:: THREAD_MODE_BACKGROUND_END => WinAPIThreadPriority :: BackgroundModeEnd ,
90- winbase:: THREAD_PRIORITY_ABOVE_NORMAL => WinAPIThreadPriority :: AboveNormal ,
91- winbase:: THREAD_PRIORITY_BELOW_NORMAL => WinAPIThreadPriority :: BelowNormal ,
92- winbase:: THREAD_PRIORITY_HIGHEST => WinAPIThreadPriority :: Highest ,
93- winbase:: THREAD_PRIORITY_IDLE => WinAPIThreadPriority :: Idle ,
94- winbase:: THREAD_PRIORITY_LOWEST => WinAPIThreadPriority :: Lowest ,
95- winbase:: THREAD_PRIORITY_NORMAL => WinAPIThreadPriority :: Normal ,
96- winbase:: THREAD_PRIORITY_TIME_CRITICAL => WinAPIThreadPriority :: TimeCritical ,
97- _ => {
98- return Err ( Error :: Priority (
99- "The value is out of range of allowed values." ,
100- ) )
112+ ThreadPriority :: Os ( crate :: ThreadPriorityOsValue ( p) ) => {
113+ match THREAD_PRIORITY ( p as i32 ) {
114+ THREAD_MODE_BACKGROUND_BEGIN => WinAPIThreadPriority :: BackgroundModeBegin ,
115+ THREAD_MODE_BACKGROUND_END => WinAPIThreadPriority :: BackgroundModeEnd ,
116+ THREAD_PRIORITY_ABOVE_NORMAL => WinAPIThreadPriority :: AboveNormal ,
117+ THREAD_PRIORITY_BELOW_NORMAL => WinAPIThreadPriority :: BelowNormal ,
118+ THREAD_PRIORITY_HIGHEST => WinAPIThreadPriority :: Highest ,
119+ THREAD_PRIORITY_IDLE => WinAPIThreadPriority :: Idle ,
120+ THREAD_PRIORITY_LOWEST => WinAPIThreadPriority :: Lowest ,
121+ THREAD_PRIORITY_NORMAL => WinAPIThreadPriority :: Normal ,
122+ THREAD_PRIORITY_TIME_CRITICAL => WinAPIThreadPriority :: TimeCritical ,
123+ _ => {
124+ return Err ( Error :: Priority (
125+ "The value is out of range of allowed values." ,
126+ ) )
127+ }
101128 }
102- } ,
129+ }
103130 ThreadPriority :: Max => WinAPIThreadPriority :: Highest ,
104131 } )
105132 }
106133}
107134
108- impl std:: convert:: TryFrom < DWORD > for WinAPIThreadPriority {
135+ impl std:: convert:: TryFrom < THREAD_PRIORITY > for WinAPIThreadPriority {
109136 type Error = crate :: Error ;
110137
111- fn try_from ( priority : DWORD ) -> Result < Self , Self :: Error > {
138+ fn try_from ( priority : THREAD_PRIORITY ) -> Result < Self , Self :: Error > {
112139 Ok ( match priority {
113- winbase :: THREAD_MODE_BACKGROUND_BEGIN => WinAPIThreadPriority :: BackgroundModeBegin ,
114- winbase :: THREAD_MODE_BACKGROUND_END => WinAPIThreadPriority :: BackgroundModeEnd ,
115- winbase :: THREAD_PRIORITY_ABOVE_NORMAL => WinAPIThreadPriority :: AboveNormal ,
116- winbase :: THREAD_PRIORITY_BELOW_NORMAL => WinAPIThreadPriority :: BelowNormal ,
117- winbase :: THREAD_PRIORITY_HIGHEST => WinAPIThreadPriority :: Highest ,
118- winbase :: THREAD_PRIORITY_IDLE => WinAPIThreadPriority :: Idle ,
119- winbase :: THREAD_PRIORITY_LOWEST => WinAPIThreadPriority :: Lowest ,
120- winbase :: THREAD_PRIORITY_NORMAL => WinAPIThreadPriority :: Normal ,
121- winbase :: THREAD_PRIORITY_TIME_CRITICAL => WinAPIThreadPriority :: TimeCritical ,
140+ THREAD_MODE_BACKGROUND_BEGIN => WinAPIThreadPriority :: BackgroundModeBegin ,
141+ THREAD_MODE_BACKGROUND_END => WinAPIThreadPriority :: BackgroundModeEnd ,
142+ THREAD_PRIORITY_ABOVE_NORMAL => WinAPIThreadPriority :: AboveNormal ,
143+ THREAD_PRIORITY_BELOW_NORMAL => WinAPIThreadPriority :: BelowNormal ,
144+ THREAD_PRIORITY_HIGHEST => WinAPIThreadPriority :: Highest ,
145+ THREAD_PRIORITY_IDLE => WinAPIThreadPriority :: Idle ,
146+ THREAD_PRIORITY_LOWEST => WinAPIThreadPriority :: Lowest ,
147+ THREAD_PRIORITY_NORMAL => WinAPIThreadPriority :: Normal ,
148+ THREAD_PRIORITY_TIME_CRITICAL => WinAPIThreadPriority :: TimeCritical ,
122149 _ => return Err ( Error :: Priority ( "Priority couldn't be parsed" ) ) ,
123150 } )
124151 }
@@ -173,11 +200,8 @@ pub fn set_winapi_thread_priority(
173200 priority : WinAPIThreadPriority ,
174201) -> Result < ( ) , Error > {
175202 unsafe {
176- if SetThreadPriority ( native, priority as c_int ) != 0 {
177- Ok ( ( ) )
178- } else {
179- Err ( Error :: OS ( GetLastError ( ) as i32 ) )
180- }
203+ SetThreadPriority ( native. 0 , THREAD_PRIORITY ( priority as i32 ) )
204+ . map_err ( |e| Error :: OS ( e. code ( ) . 0 ) )
181205 }
182206}
183207
@@ -198,7 +222,6 @@ pub fn set_winapi_thread_priority(
198222///
199223/// If there's an error, a result of
200224/// [`GetLastError`](https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror) is returned.
201-
202225pub fn set_current_thread_priority ( priority : ThreadPriority ) -> Result < ( ) , Error > {
203226 let thread_id = thread_native_id ( ) ;
204227 set_thread_priority ( thread_id, priority)
@@ -217,13 +240,13 @@ pub fn set_current_thread_priority(priority: ThreadPriority) -> Result<(), Error
217240/// ```
218241pub fn get_thread_priority ( native : ThreadId ) -> Result < ThreadPriority , Error > {
219242 unsafe {
220- let ret = GetThreadPriority ( native) ;
221- if ret as u32 != winbase :: THREAD_PRIORITY_ERROR_RETURN {
222- Ok ( ThreadPriority :: Os ( crate :: ThreadPriorityOsValue (
223- WinAPIThreadPriority :: try_from ( ret as DWORD ) ? as u32 ,
243+ let ret = GetThreadPriority ( native. 0 ) ;
244+ if ret as u32 != THREAD_PRIORITY_ERROR_RETURN {
245+ Ok ( ThreadPriority :: Os ( crate :: ThreadPriorityOsValue :: from (
246+ WinAPIThreadPriority :: try_from ( THREAD_PRIORITY ( ret) ) ? ,
224247 ) ) )
225248 } else {
226- Err ( Error :: OS ( GetLastError ( ) as i32 ) )
249+ Err ( Error :: OS ( GetLastError ( ) . 0 as i32 ) )
227250 }
228251 }
229252}
@@ -241,13 +264,13 @@ pub fn get_thread_priority(native: ThreadId) -> Result<ThreadPriority, Error> {
241264/// ```
242265pub fn get_current_thread_priority ( ) -> Result < ThreadPriority , Error > {
243266 unsafe {
244- let ret = GetThreadPriority ( thread_native_id ( ) ) ;
245- if ret as u32 != winbase :: THREAD_PRIORITY_ERROR_RETURN {
246- Ok ( ThreadPriority :: Os ( crate :: ThreadPriorityOsValue (
247- WinAPIThreadPriority :: try_from ( ret as DWORD ) ? as u32 ,
267+ let ret = GetThreadPriority ( thread_native_id ( ) . 0 ) ;
268+ if ret as u32 != THREAD_PRIORITY_ERROR_RETURN {
269+ Ok ( ThreadPriority :: Os ( crate :: ThreadPriorityOsValue :: from (
270+ WinAPIThreadPriority :: try_from ( THREAD_PRIORITY ( ret) ) ? ,
248271 ) ) )
249272 } else {
250- Err ( Error :: OS ( GetLastError ( ) as i32 ) )
273+ Err ( Error :: OS ( GetLastError ( ) . 0 as i32 ) )
251274 }
252275 }
253276}
@@ -261,10 +284,10 @@ pub fn get_current_thread_priority() -> Result<ThreadPriority, Error> {
261284/// ```rust
262285/// use thread_priority::thread_native_id;
263286///
264- /// assert!(!thread_native_id().is_null ());
287+ /// assert!(!thread_native_id().is_invalid ());
265288/// ```
266289pub fn thread_native_id ( ) -> ThreadId {
267- unsafe { GetCurrentThread ( ) }
290+ ThreadId ( unsafe { GetCurrentThread ( ) } )
268291}
269292
270293/// Disables or enables the ability of the system to temporarily boost the priority of a thread.
@@ -281,13 +304,7 @@ pub fn thread_native_id() -> ThreadId {
281304/// assert!(set_thread_priority_boost(thread_id, false).is_ok())
282305/// ```
283306pub fn set_thread_priority_boost ( native : ThreadId , enabled : bool ) -> Result < ( ) , Error > {
284- unsafe {
285- if SetThreadPriorityBoost ( native, enabled as i32 ) != 0 {
286- Ok ( ( ) )
287- } else {
288- Err ( Error :: OS ( GetLastError ( ) as i32 ) )
289- }
290- }
307+ unsafe { SetThreadPriorityBoost ( native. 0 , enabled) . map_err ( |e| Error :: OS ( e. code ( ) . 0 ) ) }
291308}
292309
293310/// Disables or enables the ability of the system to temporarily boost the priority of a current thread.
@@ -327,9 +344,9 @@ pub fn set_thread_ideal_processor(
327344 ideal_processor : IdealProcessor ,
328345) -> Result < IdealProcessor , Error > {
329346 unsafe {
330- let ret = SetThreadIdealProcessor ( native, ideal_processor) ;
331- if ret == IdealProcessor :: max_value ( ) - 1 {
332- Err ( Error :: OS ( GetLastError ( ) as i32 ) )
347+ let ret = SetThreadIdealProcessor ( native. 0 , ideal_processor) ;
348+ if ret == u32 :: MAX {
349+ Err ( Error :: OS ( GetLastError ( ) . 0 as i32 ) )
333350 } else {
334351 Ok ( ret)
335352 }
@@ -350,18 +367,20 @@ impl std::convert::TryFrom<u32> for crate::ThreadPriorityOsValue {
350367 type Error = ( ) ;
351368
352369 fn try_from ( value : u32 ) -> Result < Self , Self :: Error > {
353- Ok ( crate :: ThreadPriorityOsValue ( match value {
354- winbase:: THREAD_MODE_BACKGROUND_BEGIN
355- | winbase:: THREAD_MODE_BACKGROUND_END
356- | winbase:: THREAD_PRIORITY_ABOVE_NORMAL
357- | winbase:: THREAD_PRIORITY_BELOW_NORMAL
358- | winbase:: THREAD_PRIORITY_HIGHEST
359- | winbase:: THREAD_PRIORITY_IDLE
360- | winbase:: THREAD_PRIORITY_LOWEST
361- | winbase:: THREAD_PRIORITY_NORMAL
362- | winbase:: THREAD_PRIORITY_TIME_CRITICAL => value,
363- _ => return Err ( ( ) ) ,
364- } ) )
370+ Ok ( crate :: ThreadPriorityOsValue (
371+ match THREAD_PRIORITY ( value as i32 ) {
372+ THREAD_MODE_BACKGROUND_BEGIN
373+ | THREAD_MODE_BACKGROUND_END
374+ | THREAD_PRIORITY_ABOVE_NORMAL
375+ | THREAD_PRIORITY_BELOW_NORMAL
376+ | THREAD_PRIORITY_HIGHEST
377+ | THREAD_PRIORITY_IDLE
378+ | THREAD_PRIORITY_LOWEST
379+ | THREAD_PRIORITY_NORMAL
380+ | THREAD_PRIORITY_TIME_CRITICAL => value,
381+ _ => return Err ( ( ) ) ,
382+ } ,
383+ ) )
365384 }
366385}
367386
@@ -397,7 +416,7 @@ pub trait ThreadExt {
397416 /// ```rust
398417 /// use thread_priority::*;
399418 ///
400- /// assert!(!std::thread::current().get_native_id().unwrap().is_null ());
419+ /// assert!(!std::thread::current().get_native_id().unwrap().is_invalid ());
401420 /// ```
402421 fn get_native_id ( & self ) -> Result < ThreadId , Error > ;
403422
0 commit comments