Commit f3d41cc7 authored by Alexandre Julliard's avatar Alexandre Julliard

server: Don't bother queuing APC_NONE apcs.

parent 0b2cb328
...@@ -2738,6 +2738,8 @@ static void test_QueueUserAPC(void) ...@@ -2738,6 +2738,8 @@ static void test_QueueUserAPC(void)
ret = pNtQueueApcThread(thread, call_user_apc, (ULONG_PTR)user_apc, 0, 0); ret = pNtQueueApcThread(thread, call_user_apc, (ULONG_PTR)user_apc, 0, 0);
ok(ret == STATUS_UNSUCCESSFUL, "got %#x\n", ret); ok(ret == STATUS_UNSUCCESSFUL, "got %#x\n", ret);
ret = pNtQueueApcThread(thread, NULL, 0, 0, 0);
ok(ret == STATUS_UNSUCCESSFUL, "got %#x\n", ret);
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = QueueUserAPC(user_apc, thread, 0); ret = QueueUserAPC(user_apc, thread, 0);
...@@ -2745,6 +2747,16 @@ static void test_QueueUserAPC(void) ...@@ -2745,6 +2747,16 @@ static void test_QueueUserAPC(void)
ok(GetLastError() == ERROR_GEN_FAILURE, "got %u\n", GetLastError()); ok(GetLastError() == ERROR_GEN_FAILURE, "got %u\n", GetLastError());
CloseHandle(thread); CloseHandle(thread);
ret = QueueUserAPC(user_apc, GetCurrentThread(), 0);
ok(ret, "QueueUserAPC failed err %u\n", GetLastError());
ret = SleepEx( 100, TRUE );
ok( ret == WAIT_IO_COMPLETION, "SleepEx returned %u\n", ret);
ret = pNtQueueApcThread( GetCurrentThread(), NULL, 0, 0, 0 );
ok( !ret, "got %#x\n", ret);
ret = SleepEx( 100, TRUE );
ok( ret == WAIT_OBJECT_0, "SleepEx returned %u\n", ret);
} }
START_TEST(sync) START_TEST(sync)
......
...@@ -1061,6 +1061,7 @@ static inline struct list *get_apc_queue( struct thread *thread, enum apc_type t ...@@ -1061,6 +1061,7 @@ static inline struct list *get_apc_queue( struct thread *thread, enum apc_type t
switch(type) switch(type)
{ {
case APC_NONE: case APC_NONE:
return NULL;
case APC_USER: case APC_USER:
case APC_TIMER: case APC_TIMER:
return &thread->user_apc; return &thread->user_apc;
...@@ -1111,12 +1112,12 @@ static int queue_apc( struct process *process, struct thread *thread, struct thr ...@@ -1111,12 +1112,12 @@ static int queue_apc( struct process *process, struct thread *thread, struct thr
} }
} }
if (!thread) return 0; /* nothing found */ if (!thread) return 0; /* nothing found */
queue = get_apc_queue( thread, apc->call.type ); if (!(queue = get_apc_queue( thread, apc->call.type ))) return 1;
} }
else else
{ {
if (thread->state == TERMINATED) return 0; if (thread->state == TERMINATED) return 0;
queue = get_apc_queue( thread, apc->call.type ); if (!(queue = get_apc_queue( thread, apc->call.type ))) return 1;
/* send signal for system APCs if needed */ /* send signal for system APCs if needed */
if (queue == &thread->system_apc && list_empty( queue ) && !is_in_apc_wait( thread )) if (queue == &thread->system_apc && list_empty( queue ) && !is_in_apc_wait( thread ))
{ {
...@@ -1640,13 +1641,8 @@ DECL_HANDLER(select) ...@@ -1640,13 +1641,8 @@ DECL_HANDLER(select)
while (get_error() == STATUS_USER_APC) while (get_error() == STATUS_USER_APC)
{ {
if (!(apc = thread_dequeue_apc( current, 0 ))) apc = thread_dequeue_apc( current, 0 );
break; if ((reply->apc_handle = alloc_handle( current->process, apc, SYNCHRONIZE, 0 )))
/* Optimization: ignore APC_NONE calls, they are only used to
* wake up a thread, but since we got here the thread woke up already.
*/
if (apc->call.type != APC_NONE &&
(reply->apc_handle = alloc_handle( current->process, apc, SYNCHRONIZE, 0 )))
{ {
reply->call = apc->call; reply->call = apc->call;
release_object( apc ); release_object( apc );
......
...@@ -126,15 +126,12 @@ static void timer_callback( void *private ) ...@@ -126,15 +126,12 @@ static void timer_callback( void *private )
{ {
apc_call_t data; apc_call_t data;
assert (timer->callback);
memset( &data, 0, sizeof(data) ); memset( &data, 0, sizeof(data) );
if (timer->callback) data.type = APC_TIMER;
{ data.user.timer.func = timer->callback;
data.type = APC_TIMER; data.user.timer.time = timer->when;
data.user.timer.func = timer->callback; data.user.timer.arg = timer->arg;
data.user.timer.time = timer->when;
data.user.timer.arg = timer->arg;
}
else data.type = APC_NONE; /* wake up only */
if (!thread_queue_apc( NULL, timer->thread, &timer->obj, &data )) if (!thread_queue_apc( NULL, timer->thread, &timer->obj, &data ))
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment