2 * Server-side support for async i/o operations
4 * Copyright (C) 1998 Alexandre Julliard
5 * Copyright (C) 2000 Mike McCormack
23 void destroy_async( struct async
*async
)
25 struct async_queue
*aq
= async
->q
;
27 /*fprintf(stderr,"destroyed async %p\n",async->overlapped); */
30 remove_timeout_user(async
->timeout
);
31 async
->timeout
= NULL
;
34 async
->prev
->next
= async
->next
;
36 aq
->head
= async
->next
;
39 async
->next
->prev
= async
->prev
;
41 aq
->tail
= async
->prev
;
50 void async_notify(struct async
*async
, int status
)
52 /* fprintf(stderr,"notifying %p!\n",async->overlapped); */
53 async
->status
= status
;
54 thread_queue_apc(async
->thread
, NULL
, async
->func
, APC_ASYNC
, 1, 2, async
->overlapped
, status
);
57 void destroy_async_queue( struct async_queue
*q
)
61 async_notify(q
->head
, STATUS_HANDLES_CLOSED
);
62 destroy_async(q
->head
);
66 struct async
*find_async(struct async_queue
*q
, struct thread
*thread
, void *overlapped
)
70 /* fprintf(stderr,"find_async: %p\n",overlapped); */
75 for(async
= q
->head
; async
; async
= async
->next
)
76 if((async
->overlapped
==overlapped
) && (async
->thread
== thread
))
82 void async_insert(struct async_queue
*q
, struct async
*async
)
85 async
->prev
= q
->tail
;
89 q
->tail
->next
= async
;
96 static void async_callback(void *private)
98 struct async
*async
= (struct async
*)private;
100 /* fprintf(stderr,"%p timeout out\n",async->overlapped); */
101 async
->timeout
= NULL
;
102 async_notify(async
, STATUS_TIMEOUT
);
103 destroy_async(async
);
106 struct async
*create_async(struct object
*obj
, struct thread
*thread
, void *func
,
109 struct async
*async
= (struct async
*) malloc(sizeof(struct async
));
112 set_error(STATUS_NO_MEMORY
);
117 async
->thread
= thread
;
119 async
->overlapped
= overlapped
;
123 async
->status
= STATUS_PENDING
;
124 async
->timeout
= NULL
;
129 void async_add_timeout(struct async
*async
, int timeout
)
133 gettimeofday( &async
->when
, 0 );
134 add_timeout( &async
->when
, timeout
);
135 async
->timeout
= add_timeout_user( &async
->when
, async_callback
, async
);
139 DECL_HANDLER(register_async
)
143 if (!(obj
= get_handle_obj( current
->process
, req
->handle
, 0, NULL
)) )
146 if(obj
->ops
->queue_async
)
148 struct async_queue
*q
= obj
->ops
->queue_async(obj
, NULL
, req
->type
, 0);
151 async
= find_async(q
, current
, req
->overlapped
);
152 if(req
->status
==STATUS_PENDING
)
155 async
= create_async(obj
, current
, req
->func
, req
->overlapped
);
159 async
->status
= req
->status
;
160 if(!obj
->ops
->queue_async(obj
, async
, req
->type
, req
->count
))
161 destroy_async(async
);
167 destroy_async(async
);
169 set_error(STATUS_INVALID_PARAMETER
);
172 set_select_events(obj
,obj
->ops
->get_poll_events(obj
));
175 set_error(STATUS_INVALID_HANDLE
);