Convert the APC queues to use standard lists.

This commit is contained in:
Alexandre Julliard 2005-02-25 14:01:40 +00:00
parent 9abbc913d2
commit 81b6a1fbe5
2 changed files with 20 additions and 38 deletions

View File

@ -62,8 +62,7 @@ struct thread_wait
struct thread_apc
{
struct thread_apc *next; /* queue linked list */
struct thread_apc *prev;
struct list entry; /* queue linked list */
struct object *owner; /* object that queued this apc */
void *func; /* function to call in client */
enum apc_type type; /* type of apc function */
@ -121,10 +120,6 @@ inline static void init_thread_structure( struct thread *thread )
thread->debug_event = NULL;
thread->queue = NULL;
thread->wait = NULL;
thread->system_apc.head = NULL;
thread->system_apc.tail = NULL;
thread->user_apc.head = NULL;
thread->user_apc.tail = NULL;
thread->error = 0;
thread->req_data = NULL;
thread->req_toread = 0;
@ -144,6 +139,9 @@ inline static void init_thread_structure( struct thread *thread )
thread->creation_time = time(NULL);
thread->exit_time = 0;
list_init( &thread->system_apc );
list_init( &thread->user_apc );
for (i = 0; i < MAX_INFLIGHT_FDS; i++)
thread->inflight[i].server = thread->inflight[i].client = -1;
}
@ -451,8 +449,8 @@ static int check_wait( struct thread *thread )
}
other_checks:
if ((wait->flags & SELECT_INTERRUPTIBLE) && thread->system_apc.head) return STATUS_USER_APC;
if ((wait->flags & SELECT_ALERTABLE) && thread->user_apc.head) return STATUS_USER_APC;
if ((wait->flags & SELECT_INTERRUPTIBLE) && !list_empty(&thread->system_apc)) return STATUS_USER_APC;
if ((wait->flags & SELECT_ALERTABLE) && !list_empty(&thread->user_apc)) return STATUS_USER_APC;
if (wait->flags & SELECT_TIMEOUT)
{
struct timeval now;
@ -588,28 +586,22 @@ int thread_queue_apc( struct thread *thread, struct object *owner, void *func,
enum apc_type type, int system, void *arg1, void *arg2, void *arg3 )
{
struct thread_apc *apc;
struct apc_queue *queue = system ? &thread->system_apc : &thread->user_apc;
struct list *queue = system ? &thread->system_apc : &thread->user_apc;
/* cancel a possible previous APC with the same owner */
if (owner) thread_cancel_apc( thread, owner, system );
if (thread->state == TERMINATED) return 0;
if (!(apc = mem_alloc( sizeof(*apc) ))) return 0;
apc->prev = queue->tail;
apc->next = NULL;
apc->owner = owner;
apc->func = func;
apc->type = type;
apc->arg1 = arg1;
apc->arg2 = arg2;
apc->arg3 = arg3;
queue->tail = apc;
if (!apc->prev) /* first one */
{
queue->head = apc;
list_add_tail( queue, &apc->entry );
if (!list_prev( queue, &apc->entry )) /* first one */
wake_thread( thread );
}
else apc->prev->next = apc;
return 1;
}
@ -618,14 +610,11 @@ int thread_queue_apc( struct thread *thread, struct object *owner, void *func,
void thread_cancel_apc( struct thread *thread, struct object *owner, int system )
{
struct thread_apc *apc;
struct apc_queue *queue = system ? &thread->system_apc : &thread->user_apc;
for (apc = queue->head; apc; apc = apc->next)
struct list *queue = system ? &thread->system_apc : &thread->user_apc;
LIST_FOR_EACH_ENTRY( apc, queue, struct thread_apc, entry )
{
if (apc->owner != owner) continue;
if (apc->next) apc->next->prev = apc->prev;
else queue->tail = apc->prev;
if (apc->prev) apc->prev->next = apc->next;
else queue->head = apc->next;
list_remove( &apc->entry );
free( apc );
return;
}
@ -634,15 +623,14 @@ void thread_cancel_apc( struct thread *thread, struct object *owner, int system
/* remove the head apc from the queue; the returned pointer must be freed by the caller */
static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system_only )
{
struct thread_apc *apc;
struct apc_queue *queue = &thread->system_apc;
struct thread_apc *apc = NULL;
struct list *ptr = list_head( &thread->system_apc );
if (!queue->head && !system_only) queue = &thread->user_apc;
if ((apc = queue->head))
if (!ptr && !system_only) ptr = list_head( &thread->user_apc );
if (ptr)
{
if (apc->next) apc->next->prev = NULL;
else queue->tail = NULL;
queue->head = apc->next;
apc = LIST_ENTRY( ptr, struct thread_apc, entry );
list_remove( ptr );
}
return apc;
}

View File

@ -40,12 +40,6 @@ enum run_state
TERMINATED /* terminated */
};
struct apc_queue
{
struct thread_apc *head;
struct thread_apc *tail;
};
/* descriptor for fds currently in flight from client to server */
struct inflight_fd
{
@ -68,8 +62,8 @@ struct thread
struct debug_event *debug_event; /* debug event being sent to debugger */
struct msg_queue *queue; /* message queue */
struct thread_wait *wait; /* current wait condition if sleeping */
struct apc_queue system_apc; /* queue of system async procedure calls */
struct apc_queue user_apc; /* queue of user async procedure calls */
struct list system_apc; /* queue of system async procedure calls */
struct list user_apc; /* queue of user async procedure calls */
struct inflight_fd inflight[MAX_INFLIGHT_FDS]; /* fds currently in flight */
unsigned int error; /* current error code */
union generic_request req; /* current request */