server: Don't wait for client thread to enter suspended state in set_thread_context.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
2960a973d1
commit
aa0c4bb5e7
|
@ -787,42 +787,16 @@ TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void)
|
||||||
NTSTATUS set_thread_context( HANDLE handle, const context_t *context, BOOL *self )
|
NTSTATUS set_thread_context( HANDLE handle, const context_t *context, BOOL *self )
|
||||||
{
|
{
|
||||||
NTSTATUS ret;
|
NTSTATUS ret;
|
||||||
DWORD dummy, i;
|
|
||||||
|
|
||||||
SERVER_START_REQ( set_thread_context )
|
SERVER_START_REQ( set_thread_context )
|
||||||
{
|
{
|
||||||
req->handle = wine_server_obj_handle( handle );
|
req->handle = wine_server_obj_handle( handle );
|
||||||
req->suspend = 1;
|
|
||||||
wine_server_add_data( req, context, sizeof(*context) );
|
wine_server_add_data( req, context, sizeof(*context) );
|
||||||
ret = wine_server_call( req );
|
ret = wine_server_call( req );
|
||||||
*self = reply->self;
|
*self = reply->self;
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
if (ret == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
for (i = 0; i < 100; i++)
|
|
||||||
{
|
|
||||||
SERVER_START_REQ( set_thread_context )
|
|
||||||
{
|
|
||||||
req->handle = wine_server_obj_handle( handle );
|
|
||||||
req->suspend = 0;
|
|
||||||
wine_server_add_data( req, context, sizeof(*context) );
|
|
||||||
ret = wine_server_call( req );
|
|
||||||
}
|
|
||||||
SERVER_END_REQ;
|
|
||||||
if (ret == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
LARGE_INTEGER timeout;
|
|
||||||
timeout.QuadPart = -10000;
|
|
||||||
NtDelayExecution( FALSE, &timeout );
|
|
||||||
}
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
NtResumeThread( handle, &dummy );
|
|
||||||
if (ret == STATUS_PENDING) ret = STATUS_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1859,35 +1859,21 @@ DECL_HANDLER(set_thread_context)
|
||||||
if (!(thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT ))) return;
|
if (!(thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT ))) return;
|
||||||
reply->self = (thread == current);
|
reply->self = (thread == current);
|
||||||
|
|
||||||
if (thread != current && (!thread->context || thread->context->status == STATUS_PENDING))
|
if (thread->state == TERMINATED) set_error( STATUS_UNSUCCESSFUL );
|
||||||
{
|
else if (context->cpu != thread->process->cpu) set_error( STATUS_INVALID_PARAMETER );
|
||||||
/* thread is not suspended, retry (if it's still running) */
|
else
|
||||||
if (thread->state == RUNNING)
|
|
||||||
{
|
|
||||||
set_error( STATUS_PENDING );
|
|
||||||
if (req->suspend)
|
|
||||||
{
|
|
||||||
release_object( thread );
|
|
||||||
/* make sure we have suspend access */
|
|
||||||
if (!(thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME ))) return;
|
|
||||||
suspend_thread( thread );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else set_error( STATUS_UNSUCCESSFUL );
|
|
||||||
}
|
|
||||||
else if (context->cpu == thread->process->cpu)
|
|
||||||
{
|
{
|
||||||
unsigned int system_flags = get_context_system_regs(context->cpu) & context->flags;
|
unsigned int system_flags = get_context_system_regs(context->cpu) & context->flags;
|
||||||
unsigned int client_flags = context->flags & ~system_flags;
|
unsigned int client_flags = context->flags & ~system_flags;
|
||||||
|
|
||||||
if (system_flags) set_thread_context( thread, context, system_flags );
|
if (system_flags) set_thread_context( thread, context, system_flags );
|
||||||
|
if (thread != current && !get_error()) stop_thread( thread );
|
||||||
if (thread->context && !get_error())
|
if (thread->context && !get_error())
|
||||||
{
|
{
|
||||||
copy_context( &thread->context->regs, context, context->flags );
|
copy_context( &thread->context->regs, context, context->flags );
|
||||||
thread->context->regs.flags |= client_flags;
|
thread->context->regs.flags |= client_flags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else set_error( STATUS_INVALID_PARAMETER );
|
|
||||||
|
|
||||||
release_object( thread );
|
release_object( thread );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue