diff --git a/server/hook.c b/server/hook.c index 83b540b99f2..65bd3bad709 100644 --- a/server/hook.c +++ b/server/hook.c @@ -94,12 +94,12 @@ static struct hook_table *alloc_hook_table(void) static struct hook *add_hook( struct thread *thread, int index ) { struct hook *hook; - struct hook_table *table = thread ? thread->hooks : global_hooks; + struct hook_table *table = thread ? get_queue_hooks(thread) : global_hooks; if (!table) { if (!(table = alloc_hook_table())) return NULL; - if (thread) thread->hooks = table; + if (thread) set_queue_hooks( thread, table ); else global_hooks = table; } if (!(hook = mem_alloc( sizeof(*hook) ))) return NULL; @@ -129,7 +129,7 @@ static void free_hook( struct hook *hook ) static struct hook *find_hook( struct thread *thread, int index, void *proc ) { struct list *p; - struct hook_table *table = thread->hooks; + struct hook_table *table = get_queue_hooks( thread ); if (table) { @@ -145,7 +145,7 @@ static struct hook *find_hook( struct thread *thread, int index, void *proc ) /* get the hook table that a given hook belongs to */ inline static struct hook_table *get_table( struct hook *hook ) { - return hook->thread ? hook->thread->hooks : global_hooks; + return hook->thread ? get_queue_hooks(hook->thread) : global_hooks; } /* get the first hook in the chain */ @@ -304,7 +304,7 @@ DECL_HANDLER(remove_hook) DECL_HANDLER(start_hook_chain) { struct hook *hook; - struct hook_table *table = current->hooks; + struct hook_table *table = get_queue_hooks( current ); if (req->id < WH_MINHOOK || req->id > WH_MAXHOOK) { @@ -330,7 +330,7 @@ DECL_HANDLER(start_hook_chain) /* finished calling a hook chain */ DECL_HANDLER(finish_hook_chain) { - struct hook_table *table = current->hooks; + struct hook_table *table = get_queue_hooks( current ); int index = req->id - WH_MINHOOK; if (req->id < WH_MINHOOK || req->id > WH_MAXHOOK) diff --git a/server/queue.c b/server/queue.c index 5315886510d..70dfe6376d6 100644 --- a/server/queue.c +++ b/server/queue.c @@ -124,6 +124,7 @@ struct msg_queue struct timer *next_timer; /* next timer to expire */ struct timeout_user *timeout; /* timeout for next timer to expire */ struct thread_input *input; /* thread input descriptor */ + struct hook_table *hooks; /* hook table */ }; static void msg_queue_dump( struct object *obj, int verbose ); @@ -219,6 +220,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_ queue->next_timer = NULL; queue->timeout = NULL; queue->input = (struct thread_input *)grab_object( input ); + queue->hooks = NULL; for (i = 0; i < NB_MSG_KINDS; i++) queue->msg_list[i].first = queue->msg_list[i].last = NULL; @@ -251,6 +253,22 @@ void free_msg_queue( struct thread *thread ) thread->queue = NULL; } +/* get the hook table for a given thread */ +struct hook_table *get_queue_hooks( struct thread *thread ) +{ + if (!thread->queue) return NULL; + return thread->queue->hooks; +} + +/* set the hook table for a given thread, allocating the queue if needed */ +void set_queue_hooks( struct thread *thread, struct hook_table *hooks ) +{ + struct msg_queue *queue = thread->queue; + if (!queue) queue = create_msg_queue( thread, NULL ); + if (queue->hooks) release_object( queue->hooks ); + queue->hooks = hooks; +} + /* check the queue status */ inline static int is_signaled( struct msg_queue *queue ) { @@ -645,6 +663,7 @@ static void msg_queue_destroy( struct object *obj ) } if (queue->timeout) remove_timeout_user( queue->timeout ); if (queue->input) release_object( queue->input ); + if (queue->hooks) release_object( queue->hooks ); } static void thread_input_dump( struct object *obj, int verbose ) diff --git a/server/thread.c b/server/thread.c index a600bf149f1..799ede57dde 100644 --- a/server/thread.c +++ b/server/thread.c @@ -118,7 +118,6 @@ inline static void init_thread_structure( struct thread *thread ) thread->debug_ctx = NULL; thread->debug_event = NULL; thread->queue = NULL; - thread->hooks = NULL; thread->wait = NULL; thread->system_apc.head = NULL; thread->system_apc.tail = NULL; @@ -208,7 +207,6 @@ static void cleanup_thread( struct thread *thread ) if (thread->request_fd) release_object( thread->request_fd ); if (thread->reply_fd) release_object( thread->reply_fd ); if (thread->wait_fd) release_object( thread->wait_fd ); - if (thread->hooks) release_object( thread->hooks ); free_msg_queue( thread ); cleanup_clipboard_thread(thread); destroy_thread_windows( thread ); @@ -225,7 +223,6 @@ static void cleanup_thread( struct thread *thread ) thread->request_fd = NULL; thread->reply_fd = NULL; thread->wait_fd = NULL; - thread->hooks = NULL; if (thread == booting_thread) /* killing booting thread */ { diff --git a/server/thread.h b/server/thread.h index b0fa9c3a81e..2100518af49 100644 --- a/server/thread.h +++ b/server/thread.h @@ -32,7 +32,6 @@ struct mutex; struct debug_ctx; struct debug_event; struct msg_queue; -struct hook_table; enum run_state { @@ -67,7 +66,6 @@ struct thread struct debug_ctx *debug_ctx; /* debugger context if this thread is a debugger */ struct debug_event *debug_event; /* debug event being sent to debugger */ struct msg_queue *queue; /* message queue */ - struct hook_table *hooks; /* hooks table */ struct thread_wait *wait; /* current wait condition if sleeping */ struct apc_queue system_apc; /* queue of system async procedure calls */ struct apc_queue user_apc; /* queue of user async procedure calls */ diff --git a/server/user.h b/server/user.h index 0d038b6934c..e4229a08b75 100644 --- a/server/user.h +++ b/server/user.h @@ -26,6 +26,7 @@ struct thread; struct window; struct msg_queue; +struct hook_table; enum user_object { @@ -53,6 +54,8 @@ extern void close_global_hooks(void); /* queue functions */ extern void free_msg_queue( struct thread *thread ); +extern struct hook_table *get_queue_hooks( struct thread *thread ); +extern void set_queue_hooks( struct thread *thread, struct hook_table *hooks ); extern void inc_queue_paint_count( struct thread *thread, int incr ); extern void queue_cleanup_window( struct thread *thread, user_handle_t win ); extern int attach_thread_input( struct thread *thread_from, struct thread *thread_to );