From: Marc-Aurel Zent mzent@codeweavers.com
--- server/thread.c | 27 +++++++++++++++++++++------ server/thread.h | 4 +++- 2 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/server/thread.c b/server/thread.c index d5fa28124b8..e65bcb3485e 100644 --- a/server/thread.c +++ b/server/thread.c @@ -405,6 +405,7 @@ static inline void init_thread_structure( struct thread *thread ) thread->wait_fd = NULL; thread->state = RUNNING; thread->exit_code = 0; + thread->priority = 0; thread->base_priority = 0; thread->suspend = 0; thread->dbg_hidden = 0; @@ -771,6 +772,25 @@ affinity_t get_thread_affinity( struct thread *thread ) return mask; }
+unsigned int set_thread_priority( struct thread *thread, int priority ) +{ + int priority_class = thread->process->priority; + + if (priority < LOW_PRIORITY + 1 || priority > HIGH_PRIORITY) + return STATUS_INVALID_PARAMETER; + + if (priority_class != PROCESS_PRIOCLASS_REALTIME && priority >= LOW_REALTIME_PRIORITY) + return STATUS_PRIVILEGE_NOT_HELD; + + thread->priority = priority; + + /* if thread is gone or hasn't started yet, this will be called again from init_thread with a unix_tid */ + if (thread->state == RUNNING && thread->unix_tid != -1) + apply_thread_priority( thread, priority ); + + return STATUS_SUCCESS; +} + static int thread_priority_from_class_and_level( int priority_class, int base_priority ) { /* offsets taken from https://learn.microsoft.com/en-us/windows/win32/procthread/scheduling-priori... */ @@ -805,12 +825,7 @@ unsigned int set_thread_base_priority( struct thread *thread, int base_priority return STATUS_INVALID_PARAMETER;
thread->base_priority = base_priority; - - /* if thread is gone or hasn't started yet, this will be called again from init_thread with a unix_tid */ - if (thread->state == RUNNING && thread->unix_tid != -1) - apply_thread_priority( thread, thread_priority_from_class_and_level( priority_class, base_priority )); - - return STATUS_SUCCESS; + return set_thread_priority( thread, thread_priority_from_class_and_level( priority_class, base_priority ) ); }
/* set all information about a thread */ diff --git a/server/thread.h b/server/thread.h index 419f5987ad4..0857d50020c 100644 --- a/server/thread.h +++ b/server/thread.h @@ -81,7 +81,8 @@ struct thread client_ptr_t teb; /* TEB address (in client address space) */ client_ptr_t entry_point; /* entry point (in client address space) */ affinity_t affinity; /* affinity mask */ - int base_priority; /* priority level */ + int priority; /* priority level */ + int base_priority; /* base priority class */ int suspend; /* suspend count */ int dbg_hidden; /* hidden from debugger */ obj_handle_t desktop; /* desktop handle */ @@ -122,6 +123,7 @@ extern void thread_cancel_apc( struct thread *thread, struct object *owner, enum extern int thread_add_inflight_fd( struct thread *thread, int client, int server ); extern int thread_get_inflight_fd( struct thread *thread, int client ); extern struct token *thread_get_impersonation_token( struct thread *thread ); +extern unsigned int set_thread_priority( struct thread *thread, int priority ); extern unsigned int set_thread_base_priority( struct thread *thread, int base_priority ); extern int set_thread_affinity( struct thread *thread, affinity_t affinity ); extern int suspend_thread( struct thread *thread );