forked from Mirrors/wine-wine
server: Make thread context a server object.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>feature/deterministic
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 */
|
/* 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 )
|
||||||
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 )
|
||||||
{
|
{
|
||||||
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 )
|
||||||
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 )
|
||||||
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
|
||||||
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)
|
||||||
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( ¤t->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)
|
||||||
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( ¤t->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)
|
||||||
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)
|
||||||
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
|
||||||
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) */
|
||||||
|
|
Loading…
Reference in New Issue