Jacek Caban : server: Make thread context a server object.
Alexandre Julliard
julliard at winehq.org
Wed Apr 22 15:29:26 CDT 2020
Module: wine
Branch: master
Commit: 40e849ffa46ae3cd060e2db83305dda1c4d2648e
URL: https://source.winehq.org/git/wine.git/?a=commit;h=40e849ffa46ae3cd060e2db83305dda1c4d2648e
Author: Jacek Caban <jacek at codeweavers.com>
Date: Wed Apr 22 14:31:36 2020 +0200
server: Make thread context a server object.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
server/thread.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++----------
server/thread.h | 2 +-
2 files changed, 70 insertions(+), 15 deletions(-)
diff --git a/server/thread.c b/server/thread.c
index 534fab6597..341693b7bd 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -126,6 +126,40 @@ static const struct object_ops thread_apc_ops =
};
+/* thread CPU context */
+
+struct context
+{
+ struct object obj; /* object header */
+ context_t regs; /* context data */
+};
+
+static void dump_context( struct object *obj, int verbose );
+
+static const struct object_ops context_ops =
+{
+ sizeof(struct context), /* size */
+ dump_context, /* dump */
+ no_get_type, /* get_type */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ NULL, /* signaled */
+ no_satisfied, /* satisfied */
+ no_signal, /* signal */
+ no_get_fd, /* get_fd */
+ no_map_access, /* map_access */
+ default_get_sd, /* get_sd */
+ default_set_sd, /* set_sd */
+ no_lookup_name, /* lookup_name */
+ no_link_name, /* link_name */
+ NULL, /* unlink_name */
+ no_open_file, /* open_file */
+ no_kernel_obj_list, /* get_kernel_obj_list */
+ no_close_handle, /* close_handle */
+ no_destroy /* destroy */
+};
+
+
/* thread operations */
static void dump_thread( struct object *obj, int verbose );
@@ -221,6 +255,27 @@ static inline int is_valid_address( client_ptr_t addr )
return addr && !(addr % sizeof(int));
}
+
+/* dump a context on stdout for debugging purposes */
+static void dump_context( struct object *obj, int verbose )
+{
+ struct context *context = (struct context *)obj;
+ assert( obj->ops == &context_ops );
+
+ fprintf( stderr, "context flags=%x\n", context->regs.flags );
+}
+
+
+static struct context *create_thread_context( struct thread *thread )
+{
+ struct context *context;
+ if (!(context = alloc_object( &context_ops ))) return NULL;
+ memset( &context->regs, 0, sizeof(context->regs) );
+ context->regs.cpu = thread->process->cpu;
+ return context;
+}
+
+
/* create a new thread */
struct thread *create_thread( int fd, struct process *process, const struct security_descriptor *sd )
{
@@ -317,6 +372,11 @@ static void cleanup_thread( struct thread *thread )
{
int i;
+ if (thread->context)
+ {
+ release_object( thread->context );
+ thread->context = NULL;
+ }
clear_apc_queue( &thread->system_apc );
clear_apc_queue( &thread->user_apc );
free( thread->req_data );
@@ -324,7 +384,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 );
- free( thread->context );
cleanup_clipboard_thread(thread);
destroy_thread_windows( thread );
free_msg_queue( thread );
@@ -343,7 +402,6 @@ static void cleanup_thread( struct thread *thread )
thread->request_fd = NULL;
thread->reply_fd = NULL;
thread->wait_fd = NULL;
- thread->context = NULL;
thread->desktop = 0;
thread->desc = NULL;
thread->desc_len = 0;
@@ -776,9 +834,9 @@ static int send_thread_wakeup( struct thread *thread, client_ptr_t cookie, int s
if (thread->context && thread->suspend_cookie == cookie
&& signaled != STATUS_KERNEL_APC && signaled != STATUS_USER_APC)
{
- if (!thread->context->flags)
+ if (!thread->context->regs.flags)
{
- free( thread->context );
+ release_object( thread->context );
thread->context = NULL;
}
else signaled = STATUS_KERNEL_APC; /* signal a fake APC so that client calls select to get a new context */
@@ -1556,9 +1614,8 @@ DECL_HANDLER(select)
return;
}
- if (!(current->context = mem_alloc( sizeof(*context) ))) return;
- memcpy( current->context, context, sizeof(*context) );
- current->context->flags = 0; /* to keep track of what is modified */
+ if (!(current->context = create_thread_context( current ))) return;
+ copy_context( ¤t->context->regs, context, context->flags );
current->suspend_cookie = req->cookie;
}
@@ -1633,10 +1690,8 @@ DECL_HANDLER(select)
else if (get_error() != STATUS_PENDING && get_reply_max_size() == sizeof(context_t) &&
current->context && current->suspend_cookie == req->cookie)
{
- if (current->context->flags)
- set_reply_data_ptr( current->context, sizeof(context_t) );
- else
- free( current->context );
+ if (current->context->regs.flags) set_reply_data( ¤t->context->regs, sizeof(context_t) );
+ release_object( current->context );
current->context = NULL;
}
}
@@ -1777,7 +1832,7 @@ DECL_HANDLER(get_thread_context)
context->cpu = thread->process->cpu;
if (thread->context)
{
- copy_context( context, thread->context, req->flags & ~flags );
+ copy_context( context, &thread->context->regs, req->flags & ~flags );
context->flags |= req->flags & ~flags;
}
if (req->flags & flags) get_thread_context( thread, context, req->flags & flags );
@@ -1823,8 +1878,8 @@ DECL_HANDLER(set_thread_context)
if (system_flags) set_thread_context( thread, context, system_flags );
if (thread->context && !get_error())
{
- copy_context( thread->context, context, context->flags );
- thread->context->flags |= client_flags;
+ copy_context( &thread->context->regs, context, context->flags );
+ thread->context->regs.flags |= client_flags;
}
}
else set_error( STATUS_INVALID_PARAMETER );
diff --git a/server/thread.h b/server/thread.h
index b86d8d3dbe..5d12d24dd8 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -75,7 +75,7 @@ struct thread
int exit_code; /* thread exit code */
int unix_pid; /* Unix pid of client */
int unix_tid; /* Unix tid of client */
- context_t *context; /* current context */
+ struct context *context; /* current context */
client_ptr_t suspend_cookie;/* wait cookie of suspending select */
client_ptr_t teb; /* TEB address (in client address space) */
client_ptr_t entry_point; /* entry point (in client address space) */
More information about the wine-cvs
mailing list