server: Use STATUS_KERNEL_APC to indicate system APCs.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9e581ba8c5
commit
676ad9b0af
|
@ -624,7 +624,7 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie );
|
if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie );
|
||||||
if (ret != STATUS_USER_APC) break;
|
if (ret != STATUS_USER_APC && ret != STATUS_KERNEL_APC) break;
|
||||||
if (invoke_apc( &call, &result ))
|
if (invoke_apc( &call, &result ))
|
||||||
{
|
{
|
||||||
/* if we ran a user apc we have to check once more if additional apcs are queued,
|
/* if we ran a user apc we have to check once more if additional apcs are queued,
|
||||||
|
|
|
@ -2497,7 +2497,7 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
|
||||||
RtlLeaveCriticalSection( &addr_section );
|
RtlLeaveCriticalSection( &addr_section );
|
||||||
|
|
||||||
if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie );
|
if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie );
|
||||||
if (ret != STATUS_USER_APC) break;
|
if (ret != STATUS_USER_APC && ret != STATUS_KERNEL_APC) break;
|
||||||
if (invoke_apc( &call, &result ))
|
if (invoke_apc( &call, &result ))
|
||||||
{
|
{
|
||||||
/* if we ran a user apc we have to check once more if additional apcs are queued,
|
/* if we ran a user apc we have to check once more if additional apcs are queued,
|
||||||
|
|
|
@ -747,7 +747,7 @@ static int check_wait( struct thread *thread )
|
||||||
assert( wait );
|
assert( wait );
|
||||||
|
|
||||||
if ((wait->flags & SELECT_INTERRUPTIBLE) && !list_empty( &thread->system_apc ))
|
if ((wait->flags & SELECT_INTERRUPTIBLE) && !list_empty( &thread->system_apc ))
|
||||||
return STATUS_USER_APC;
|
return STATUS_KERNEL_APC;
|
||||||
|
|
||||||
/* Suspended threads may not acquire locks, but they can run system APCs */
|
/* Suspended threads may not acquire locks, but they can run system APCs */
|
||||||
if (thread->process->suspend + thread->suspend > 0) return -1;
|
if (thread->process->suspend + thread->suspend > 0) return -1;
|
||||||
|
@ -1081,12 +1081,11 @@ void thread_cancel_apc( struct thread *thread, struct object *owner, enum apc_ty
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove the head apc from the queue; the returned object must be released by the caller */
|
/* remove the head apc from the queue; the returned object must be released by the caller */
|
||||||
static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system_only )
|
static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system )
|
||||||
{
|
{
|
||||||
struct thread_apc *apc = NULL;
|
struct thread_apc *apc = NULL;
|
||||||
struct list *ptr = list_head( &thread->system_apc );
|
struct list *ptr = list_head( system ? &thread->system_apc : &thread->user_apc );
|
||||||
|
|
||||||
if (!ptr && !system_only) ptr = list_head( &thread->user_apc );
|
|
||||||
if (ptr)
|
if (ptr)
|
||||||
{
|
{
|
||||||
apc = LIST_ENTRY( ptr, struct thread_apc, entry );
|
apc = LIST_ENTRY( ptr, struct thread_apc, entry );
|
||||||
|
@ -1581,7 +1580,7 @@ DECL_HANDLER(select)
|
||||||
|
|
||||||
while (get_error() == STATUS_USER_APC)
|
while (get_error() == STATUS_USER_APC)
|
||||||
{
|
{
|
||||||
if (!(apc = thread_dequeue_apc( current, !(req->flags & SELECT_ALERTABLE) )))
|
if (!(apc = thread_dequeue_apc( current, 0 )))
|
||||||
break;
|
break;
|
||||||
/* Optimization: ignore APC_NONE calls, they are only used to
|
/* Optimization: ignore APC_NONE calls, they are only used to
|
||||||
* wake up a thread, but since we got here the thread woke up already.
|
* wake up a thread, but since we got here the thread woke up already.
|
||||||
|
@ -1597,6 +1596,19 @@ DECL_HANDLER(select)
|
||||||
wake_up( &apc->obj, 0 );
|
wake_up( &apc->obj, 0 );
|
||||||
release_object( apc );
|
release_object( apc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (get_error() == STATUS_KERNEL_APC)
|
||||||
|
{
|
||||||
|
apc = thread_dequeue_apc( current, 1 );
|
||||||
|
if ((reply->apc_handle = alloc_handle( current->process, apc, SYNCHRONIZE, 0 )))
|
||||||
|
reply->call = apc->call;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
apc->executed = 1;
|
||||||
|
wake_up( &apc->obj, 0 );
|
||||||
|
}
|
||||||
|
release_object( apc );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* queue an APC for a thread or process */
|
/* queue an APC for a thread or process */
|
||||||
|
|
|
@ -5577,6 +5577,7 @@ static const struct
|
||||||
{ "INVALID_READ_MODE", STATUS_INVALID_READ_MODE },
|
{ "INVALID_READ_MODE", STATUS_INVALID_READ_MODE },
|
||||||
{ "INVALID_SECURITY_DESCR", STATUS_INVALID_SECURITY_DESCR },
|
{ "INVALID_SECURITY_DESCR", STATUS_INVALID_SECURITY_DESCR },
|
||||||
{ "IO_TIMEOUT", STATUS_IO_TIMEOUT },
|
{ "IO_TIMEOUT", STATUS_IO_TIMEOUT },
|
||||||
|
{ "KERNEL_APC", STATUS_KERNEL_APC },
|
||||||
{ "KEY_DELETED", STATUS_KEY_DELETED },
|
{ "KEY_DELETED", STATUS_KEY_DELETED },
|
||||||
{ "MAPPED_FILE_SIZE_ZERO", STATUS_MAPPED_FILE_SIZE_ZERO },
|
{ "MAPPED_FILE_SIZE_ZERO", STATUS_MAPPED_FILE_SIZE_ZERO },
|
||||||
{ "MORE_PROCESSING_REQUIRED", STATUS_MORE_PROCESSING_REQUIRED },
|
{ "MORE_PROCESSING_REQUIRED", STATUS_MORE_PROCESSING_REQUIRED },
|
||||||
|
|
Loading…
Reference in New Issue