From: Rémi Bernon rbernon@codeweavers.com
--- server/thread.c | 66 +++++++++++++++++++------------------------------ server/thread.h | 2 +- 2 files changed, 27 insertions(+), 41 deletions(-)
diff --git a/server/thread.c b/server/thread.c index 64cd1a74702..93b77f6b36e 100644 --- a/server/thread.c +++ b/server/thread.c @@ -391,6 +391,12 @@ static void apply_thread_priority( struct thread *thread, int effective_priority
#endif
+static void clear_inflight_fd( struct inflight_fd *fd, int need_close ) +{ + if (need_close) close( fd->server ); + fd->client = fd->server = -1; +} + /* initialize the structure for a newly allocated thread */ static inline void init_thread_structure( struct thread *thread ) { @@ -435,8 +441,7 @@ static inline void init_thread_structure( struct thread *thread ) list_init( &thread->user_apc ); list_init( &thread->kernel_object );
- for (i = 0; i < MAX_INFLIGHT_FDS; i++) - thread->inflight[i].server = thread->inflight[i].client = -1; + for (i = 0; i < MAX_INFLIGHT_FDS; i++) clear_inflight_fd( thread->inflight + i, 0 ); }
static inline int is_thread_suspended( struct thread *thread ) @@ -624,14 +629,7 @@ static void cleanup_thread( struct thread *thread ) destroy_thread_windows( thread ); free_msg_queue( thread ); release_thread_desktop( thread, 1 ); - for (i = 0; i < MAX_INFLIGHT_FDS; i++) - { - if (thread->inflight[i].client != -1) - { - close( thread->inflight[i].server ); - thread->inflight[i].client = thread->inflight[i].server = -1; - } - } + for (i = 0; i < MAX_INFLIGHT_FDS; i++) clear_inflight_fd( thread->inflight + i, 1 ); free( thread->desc ); thread->req_data = NULL; thread->reply_data = NULL; @@ -1506,56 +1504,44 @@ static void clear_apc_queue( struct list *queue ) }
/* add an fd to the inflight list */ -/* return list index, or -1 on error */ -int thread_add_inflight_fd( struct thread *thread, int client, int server ) +void thread_add_inflight_fd( struct thread *thread, int client, int server ) { - int i; + struct inflight_fd *fd, new = { .client = client, .server = server };
- if (server == -1) return -1; - if (client == -1) - { - close( server ); - return -1; - } + if (client == -1) clear_inflight_fd( &new, 1 ); + if (server == -1) return;
/* first check if we already have an entry for this fd */ - for (i = 0; i < MAX_INFLIGHT_FDS; i++) - if (thread->inflight[i].client == client) - { - close( thread->inflight[i].server ); - thread->inflight[i].server = server; - return i; - } + for (fd = thread->inflight; fd < thread->inflight + MAX_INFLIGHT_FDS; fd++) + if (fd->client == new.client) goto done;
/* now find a free spot to store it */ - for (i = 0; i < MAX_INFLIGHT_FDS; i++) - if (thread->inflight[i].client == -1) - { - thread->inflight[i].client = client; - thread->inflight[i].server = server; - return i; - } + for (fd = thread->inflight; fd < thread->inflight + MAX_INFLIGHT_FDS; fd++) + if (fd->client == -1) goto done;
- close( server ); - return -1; + fatal_error( "%04x: inflight fd array is full\n", thread->id ); + +done: + clear_inflight_fd( fd, 1 ); + *fd = new; }
/* get an inflight fd and purge it from the list */ /* the fd must be closed when no longer used */ int thread_get_inflight_fd( struct thread *thread, int client ) { - int i, ret; + struct inflight_fd *fd;
if (client == -1) return -1;
do { - for (i = 0; i < MAX_INFLIGHT_FDS; i++) + for (fd = thread->inflight; fd < thread->inflight + MAX_INFLIGHT_FDS; fd++) { - if (thread->inflight[i].client == client) + if (fd->client == client) { - ret = thread->inflight[i].server; - thread->inflight[i].server = thread->inflight[i].client = -1; + int ret = fd->server; + clear_inflight_fd( fd, 0 ); return ret; } } diff --git a/server/thread.h b/server/thread.h index b33a00d9f26..cf9bdf02e65 100644 --- a/server/thread.h +++ b/server/thread.h @@ -123,7 +123,7 @@ extern void kill_thread( struct thread *thread, int violent_death ); extern void wake_up( struct object *obj, int max ); extern int thread_queue_apc( struct process *process, struct thread *thread, struct object *owner, const union apc_call *call_data ); extern void thread_cancel_apc( struct thread *thread, struct object *owner, enum apc_type type ); -extern int thread_add_inflight_fd( struct thread *thread, int client, int server ); +extern void 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 );