Commit 40e849ff authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

server: Make thread context a server object.

parent 80ceafc2
...@@ -126,6 +126,40 @@ static const struct object_ops thread_apc_ops = ...@@ -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 */ /* thread operations */
static void dump_thread( struct object *obj, int verbose ); static void dump_thread( struct object *obj, int verbose );
...@@ -221,6 +255,27 @@ static inline int is_valid_address( client_ptr_t addr ) ...@@ -221,6 +255,27 @@ static inline int is_valid_address( client_ptr_t addr )
return addr && !(addr % sizeof(int)); 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 */ /* create a new thread */
struct thread *create_thread( int fd, struct process *process, const struct security_descriptor *sd ) 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 ) ...@@ -317,6 +372,11 @@ static void cleanup_thread( struct thread *thread )
{ {
int i; int i;
if (thread->context)
{
release_object( thread->context );
thread->context = NULL;
}
clear_apc_queue( &thread->system_apc ); clear_apc_queue( &thread->system_apc );
clear_apc_queue( &thread->user_apc ); clear_apc_queue( &thread->user_apc );
free( thread->req_data ); free( thread->req_data );
...@@ -324,7 +384,6 @@ static void cleanup_thread( struct thread *thread ) ...@@ -324,7 +384,6 @@ static void cleanup_thread( struct thread *thread )
if (thread->request_fd) release_object( thread->request_fd ); if (thread->request_fd) release_object( thread->request_fd );
if (thread->reply_fd) release_object( thread->reply_fd ); if (thread->reply_fd) release_object( thread->reply_fd );
if (thread->wait_fd) release_object( thread->wait_fd ); if (thread->wait_fd) release_object( thread->wait_fd );
free( thread->context );
cleanup_clipboard_thread(thread); cleanup_clipboard_thread(thread);
destroy_thread_windows( thread ); destroy_thread_windows( thread );
free_msg_queue( thread ); free_msg_queue( thread );
...@@ -343,7 +402,6 @@ static void cleanup_thread( struct thread *thread ) ...@@ -343,7 +402,6 @@ static void cleanup_thread( struct thread *thread )
thread->request_fd = NULL; thread->request_fd = NULL;
thread->reply_fd = NULL; thread->reply_fd = NULL;
thread->wait_fd = NULL; thread->wait_fd = NULL;
thread->context = NULL;
thread->desktop = 0; thread->desktop = 0;
thread->desc = NULL; thread->desc = NULL;
thread->desc_len = 0; thread->desc_len = 0;
...@@ -776,9 +834,9 @@ static int send_thread_wakeup( struct thread *thread, client_ptr_t cookie, int s ...@@ -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 if (thread->context && thread->suspend_cookie == cookie
&& signaled != STATUS_KERNEL_APC && signaled != STATUS_USER_APC) && 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; thread->context = NULL;
} }
else signaled = STATUS_KERNEL_APC; /* signal a fake APC so that client calls select to get a new context */ 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) ...@@ -1556,9 +1614,8 @@ DECL_HANDLER(select)
return; return;
} }
if (!(current->context = mem_alloc( sizeof(*context) ))) return; if (!(current->context = create_thread_context( current ))) return;
memcpy( current->context, context, sizeof(*context) ); copy_context( &current->context->regs, context, context->flags );
current->context->flags = 0; /* to keep track of what is modified */
current->suspend_cookie = req->cookie; current->suspend_cookie = req->cookie;
} }
...@@ -1633,10 +1690,8 @@ DECL_HANDLER(select) ...@@ -1633,10 +1690,8 @@ DECL_HANDLER(select)
else if (get_error() != STATUS_PENDING && get_reply_max_size() == sizeof(context_t) && else if (get_error() != STATUS_PENDING && get_reply_max_size() == sizeof(context_t) &&
current->context && current->suspend_cookie == req->cookie) current->context && current->suspend_cookie == req->cookie)
{ {
if (current->context->flags) if (current->context->regs.flags) set_reply_data( &current->context->regs, sizeof(context_t) );
set_reply_data_ptr( current->context, sizeof(context_t) ); release_object( current->context );
else
free( current->context );
current->context = NULL; current->context = NULL;
} }
} }
...@@ -1777,7 +1832,7 @@ DECL_HANDLER(get_thread_context) ...@@ -1777,7 +1832,7 @@ DECL_HANDLER(get_thread_context)
context->cpu = thread->process->cpu; context->cpu = thread->process->cpu;
if (thread->context) 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; context->flags |= req->flags & ~flags;
} }
if (req->flags & flags) get_thread_context( thread, context, req->flags & flags ); if (req->flags & flags) get_thread_context( thread, context, req->flags & flags );
...@@ -1823,8 +1878,8 @@ DECL_HANDLER(set_thread_context) ...@@ -1823,8 +1878,8 @@ DECL_HANDLER(set_thread_context)
if (system_flags) set_thread_context( thread, context, system_flags ); if (system_flags) set_thread_context( thread, context, system_flags );
if (thread->context && !get_error()) if (thread->context && !get_error())
{ {
copy_context( thread->context, context, context->flags ); copy_context( &thread->context->regs, context, context->flags );
thread->context->flags |= client_flags; thread->context->regs.flags |= client_flags;
} }
} }
else set_error( STATUS_INVALID_PARAMETER ); else set_error( STATUS_INVALID_PARAMETER );
......
...@@ -75,7 +75,7 @@ struct thread ...@@ -75,7 +75,7 @@ struct thread
int exit_code; /* thread exit code */ int exit_code; /* thread exit code */
int unix_pid; /* Unix pid of client */ int unix_pid; /* Unix pid of client */
int unix_tid; /* Unix tid 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 suspend_cookie;/* wait cookie of suspending select */
client_ptr_t teb; /* TEB address (in client address space) */ client_ptr_t teb; /* TEB address (in client address space) */
client_ptr_t entry_point; /* entry point (in client address space) */ client_ptr_t entry_point; /* entry point (in client address space) */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment