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,16 +109,16 @@ 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 ,
112+ ThreadPriority :: Os ( crate :: ThreadPriorityOsValue ( p) ) => match THREAD_PRIORITY ( p ) {
113+ THREAD_MODE_BACKGROUND_BEGIN => WinAPIThreadPriority :: BackgroundModeBegin ,
114+ THREAD_MODE_BACKGROUND_END => WinAPIThreadPriority :: BackgroundModeEnd ,
115+ THREAD_PRIORITY_ABOVE_NORMAL => WinAPIThreadPriority :: AboveNormal ,
116+ THREAD_PRIORITY_BELOW_NORMAL => WinAPIThreadPriority :: BelowNormal ,
117+ THREAD_PRIORITY_HIGHEST => WinAPIThreadPriority :: Highest ,
118+ THREAD_PRIORITY_IDLE => WinAPIThreadPriority :: Idle ,
119+ THREAD_PRIORITY_LOWEST => WinAPIThreadPriority :: Lowest ,
120+ THREAD_PRIORITY_NORMAL => WinAPIThreadPriority :: Normal ,
121+ THREAD_PRIORITY_TIME_CRITICAL => WinAPIThreadPriority :: TimeCritical ,
97122 _ => {
98123 return Err ( Error :: Priority (
99124 "The value is out of range of allowed values." ,
@@ -105,28 +130,28 @@ impl std::convert::TryFrom<ThreadPriority> for WinAPIThreadPriority {
105130 }
106131}
107132
108- impl std:: convert:: TryFrom < DWORD > for WinAPIThreadPriority {
133+ impl std:: convert:: TryFrom < THREAD_PRIORITY > for WinAPIThreadPriority {
109134 type Error = crate :: Error ;
110135
111- fn try_from ( priority : DWORD ) -> Result < Self , Self :: Error > {
136+ fn try_from ( priority : THREAD_PRIORITY ) -> Result < Self , Self :: Error > {
112137 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 ,
138+ THREAD_MODE_BACKGROUND_BEGIN => WinAPIThreadPriority :: BackgroundModeBegin ,
139+ THREAD_MODE_BACKGROUND_END => WinAPIThreadPriority :: BackgroundModeEnd ,
140+ THREAD_PRIORITY_ABOVE_NORMAL => WinAPIThreadPriority :: AboveNormal ,
141+ THREAD_PRIORITY_BELOW_NORMAL => WinAPIThreadPriority :: BelowNormal ,
142+ THREAD_PRIORITY_HIGHEST => WinAPIThreadPriority :: Highest ,
143+ THREAD_PRIORITY_IDLE => WinAPIThreadPriority :: Idle ,
144+ THREAD_PRIORITY_LOWEST => WinAPIThreadPriority :: Lowest ,
145+ THREAD_PRIORITY_NORMAL => WinAPIThreadPriority :: Normal ,
146+ THREAD_PRIORITY_TIME_CRITICAL => WinAPIThreadPriority :: TimeCritical ,
122147 _ => return Err ( Error :: Priority ( "Priority couldn't be parsed" ) ) ,
123148 } )
124149 }
125150}
126151
127152impl From < WinAPIThreadPriority > for crate :: ThreadPriorityOsValue {
128153 fn from ( p : WinAPIThreadPriority ) -> Self {
129- crate :: ThreadPriorityOsValue ( p as u32 )
154+ crate :: ThreadPriorityOsValue ( p as u32 as i32 )
130155 }
131156}
132157
@@ -173,11 +198,8 @@ pub fn set_winapi_thread_priority(
173198 priority : WinAPIThreadPriority ,
174199) -> Result < ( ) , Error > {
175200 unsafe {
176- if SetThreadPriority ( native, priority as c_int ) != 0 {
177- Ok ( ( ) )
178- } else {
179- Err ( Error :: OS ( GetLastError ( ) as i32 ) )
180- }
201+ SetThreadPriority ( native. 0 , THREAD_PRIORITY ( priority as i32 ) )
202+ . map_err ( |e| Error :: OS ( e. code ( ) . 0 ) )
181203 }
182204}
183205
@@ -198,7 +220,6 @@ pub fn set_winapi_thread_priority(
198220///
199221/// If there's an error, a result of
200222/// [`GetLastError`](https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror) is returned.
201-
202223pub fn set_current_thread_priority ( priority : ThreadPriority ) -> Result < ( ) , Error > {
203224 let thread_id = thread_native_id ( ) ;
204225 set_thread_priority ( thread_id, priority)
@@ -217,13 +238,13 @@ pub fn set_current_thread_priority(priority: ThreadPriority) -> Result<(), Error
217238/// ```
218239pub fn get_thread_priority ( native : ThreadId ) -> Result < ThreadPriority , Error > {
219240 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 ,
241+ let ret = GetThreadPriority ( native. 0 ) ;
242+ if ret as u32 != THREAD_PRIORITY_ERROR_RETURN {
243+ Ok ( ThreadPriority :: Os ( crate :: ThreadPriorityOsValue :: from (
244+ WinAPIThreadPriority :: try_from ( THREAD_PRIORITY ( ret) ) ? ,
224245 ) ) )
225246 } else {
226- Err ( Error :: OS ( GetLastError ( ) as i32 ) )
247+ Err ( Error :: OS ( GetLastError ( ) . 0 as i32 ) )
227248 }
228249 }
229250}
@@ -241,13 +262,13 @@ pub fn get_thread_priority(native: ThreadId) -> Result<ThreadPriority, Error> {
241262/// ```
242263pub fn get_current_thread_priority ( ) -> Result < ThreadPriority , Error > {
243264 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 ,
265+ let ret = GetThreadPriority ( thread_native_id ( ) . 0 ) ;
266+ if ret as u32 != THREAD_PRIORITY_ERROR_RETURN {
267+ Ok ( ThreadPriority :: Os ( crate :: ThreadPriorityOsValue :: from (
268+ WinAPIThreadPriority :: try_from ( THREAD_PRIORITY ( ret) ) ? ,
248269 ) ) )
249270 } else {
250- Err ( Error :: OS ( GetLastError ( ) as i32 ) )
271+ Err ( Error :: OS ( GetLastError ( ) . 0 as i32 ) )
251272 }
252273 }
253274}
@@ -261,10 +282,10 @@ pub fn get_current_thread_priority() -> Result<ThreadPriority, Error> {
261282/// ```rust
262283/// use thread_priority::thread_native_id;
263284///
264- /// assert!(!thread_native_id().is_null ());
285+ /// assert!(!thread_native_id().is_invalid ());
265286/// ```
266287pub fn thread_native_id ( ) -> ThreadId {
267- unsafe { GetCurrentThread ( ) }
288+ ThreadId ( unsafe { GetCurrentThread ( ) } )
268289}
269290
270291/// Disables or enables the ability of the system to temporarily boost the priority of a thread.
@@ -281,13 +302,7 @@ pub fn thread_native_id() -> ThreadId {
281302/// assert!(set_thread_priority_boost(thread_id, false).is_ok())
282303/// ```
283304pub 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- }
305+ unsafe { SetThreadPriorityBoost ( native. 0 , enabled) . map_err ( |e| Error :: OS ( e. code ( ) . 0 ) ) }
291306}
292307
293308/// Disables or enables the ability of the system to temporarily boost the priority of a current thread.
@@ -327,9 +342,9 @@ pub fn set_thread_ideal_processor(
327342 ideal_processor : IdealProcessor ,
328343) -> Result < IdealProcessor , Error > {
329344 unsafe {
330- let ret = SetThreadIdealProcessor ( native, ideal_processor) ;
331- if ret == IdealProcessor :: max_value ( ) - 1 {
332- Err ( Error :: OS ( GetLastError ( ) as i32 ) )
345+ let ret = SetThreadIdealProcessor ( native. 0 , ideal_processor) ;
346+ if ret == u32 :: MAX {
347+ Err ( Error :: OS ( GetLastError ( ) . 0 as i32 ) )
333348 } else {
334349 Ok ( ret)
335350 }
@@ -346,20 +361,20 @@ pub fn set_current_thread_ideal_processor(
346361 set_thread_ideal_processor ( thread_native_id ( ) , ideal_processor)
347362}
348363
349- impl std:: convert:: TryFrom < u32 > for crate :: ThreadPriorityOsValue {
364+ impl std:: convert:: TryFrom < i32 > for crate :: ThreadPriorityOsValue {
350365 type Error = ( ) ;
351366
352- 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,
367+ fn try_from ( value : i32 ) -> Result < Self , Self :: Error > {
368+ Ok ( crate :: ThreadPriorityOsValue ( match THREAD_PRIORITY ( value) {
369+ THREAD_MODE_BACKGROUND_BEGIN
370+ | THREAD_MODE_BACKGROUND_END
371+ | THREAD_PRIORITY_ABOVE_NORMAL
372+ | THREAD_PRIORITY_BELOW_NORMAL
373+ | THREAD_PRIORITY_HIGHEST
374+ | THREAD_PRIORITY_IDLE
375+ | THREAD_PRIORITY_LOWEST
376+ | THREAD_PRIORITY_NORMAL
377+ | THREAD_PRIORITY_TIME_CRITICAL => value,
363378 _ => return Err ( ( ) ) ,
364379 } ) )
365380 }
@@ -397,7 +412,7 @@ pub trait ThreadExt {
397412 /// ```rust
398413 /// use thread_priority::*;
399414 ///
400- /// assert!(!std::thread::current().get_native_id().unwrap().is_null ());
415+ /// assert!(!std::thread::current().get_native_id().unwrap().is_invalid ());
401416 /// ```
402417 fn get_native_id ( & self ) -> Result < ThreadId , Error > ;
403418
0 commit comments