server: Add support for suspending the thread directly in the get/set_thread_context requests.

This commit is contained in:
Alexandre Julliard 2011-05-06 12:31:11 +02:00
parent 45075b2f9c
commit 90982480f0
1 changed files with 26 additions and 6 deletions

View File

@ -1471,12 +1471,23 @@ DECL_HANDLER(get_thread_context)
return; return;
} }
if (!(thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) return; if (!(thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) return;
reply->self = (thread == current);
if (thread != current && !thread->context) if (thread != current && !thread->context)
{ {
/* thread is not suspended, retry (if it's still running) */ /* thread is not suspended, retry (if it's still running) */
if (thread->state != RUNNING) set_error( STATUS_ACCESS_DENIED ); if (thread->state == RUNNING)
else set_error( STATUS_PENDING ); {
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_ACCESS_DENIED );
} }
else if ((context = set_reply_data_size( sizeof(context_t) ))) else if ((context = set_reply_data_size( sizeof(context_t) )))
{ {
@ -1487,7 +1498,6 @@ DECL_HANDLER(get_thread_context)
if (thread->context) copy_context( context, thread->context, req->flags & ~flags ); if (thread->context) copy_context( context, thread->context, req->flags & ~flags );
if (flags) get_thread_context( thread, context, flags ); if (flags) get_thread_context( thread, context, flags );
} }
reply->self = (thread == current);
release_object( thread ); release_object( thread );
} }
@ -1503,12 +1513,23 @@ DECL_HANDLER(set_thread_context)
return; return;
} }
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);
if (thread != current && !thread->context) if (thread != current && !thread->context)
{ {
/* thread is not suspended, retry (if it's still running) */ /* thread is not suspended, retry (if it's still running) */
if (thread->state != RUNNING) set_error( STATUS_ACCESS_DENIED ); if (thread->state == RUNNING)
else set_error( STATUS_PENDING ); {
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_ACCESS_DENIED );
} }
else if (context->cpu == thread->process->cpu) else if (context->cpu == thread->process->cpu)
{ {
@ -1520,7 +1541,6 @@ DECL_HANDLER(set_thread_context)
} }
else set_error( STATUS_INVALID_PARAMETER ); else set_error( STATUS_INVALID_PARAMETER );
reply->self = (thread == current);
release_object( thread ); release_object( thread );
} }