server: Make thread context a server object.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
80ceafc2a1
commit
40e849ffa4
|
@ -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 );
|
||||
|
|
|
@ -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) */
|
||||
|
|
Loading…
Reference in New Issue