2 * Structures and static functions for handling asynchronous I/O.
4 * Copyright (C) 2002 Mike McCormack, Martin Wilck
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * This file declares static functions.
23 * It should only be included by those source files that implement async I/O requests.
26 #ifndef __WINE_ASYNC_H
27 #define __WINE_ASYNC_H
29 #include "wine/server.h"
33 typedef void (*async_handler)(struct async_private *ovp);
34 typedef void CALLBACK (*async_call_completion_func)(ULONG_PTR data);
35 typedef DWORD (*async_get_status)(const struct async_private *ovp);
36 typedef DWORD (*async_get_count)(const struct async_private *ovp);
37 typedef void (*async_set_status)(struct async_private *ovp, const DWORD status);
39 typedef struct async_ops
41 async_get_status get_status;
42 async_set_status set_status;
43 async_get_count get_count;
44 async_call_completion_func call_completion;
47 typedef struct async_private
49 struct async_ops *ops;
55 struct async_private *next;
56 struct async_private *prev;
59 /* All functions declared static for Dll separation purposes */
61 inline static void finish_async( async_private *ovp )
64 ovp->prev->next = ovp->next;
66 NtCurrentTeb()->pending_list = ovp->next;
69 ovp->next->prev = ovp->prev;
71 ovp->next = ovp->prev = NULL;
74 if( ovp->event != INVALID_HANDLE_VALUE )
75 NtSetEvent( ovp->event, NULL );
77 QueueUserAPC( ovp->ops->call_completion, GetCurrentThread(), (ULONG_PTR)ovp );
80 inline static BOOL __register_async( async_private *ovp, const DWORD status )
84 SERVER_START_REQ( register_async )
86 req->handle = ovp->handle;
87 req->overlapped = ovp;
88 req->type = ovp->type;
89 req->count = ovp->ops->get_count( ovp );
91 ret = wine_server_call( req );
95 if ( ret ) ovp->ops->set_status ( ovp, GetLastError() );
96 if ( ovp->ops->get_status (ovp) != STATUS_PENDING )
102 #define register_old_async(ovp) \
103 __register_async (ovp, ovp->ops->get_status( ovp ));
105 inline static BOOL register_new_async( async_private *ovp )
107 ovp->ops->set_status ( ovp, STATUS_PENDING );
109 ovp->next = NtCurrentTeb()->pending_list;
111 if ( ovp->next ) ovp->next->prev = ovp;
112 NtCurrentTeb()->pending_list = ovp;
114 return __register_async( ovp, STATUS_PENDING );
117 inline static BOOL cancel_async ( async_private *ovp )
119 /* avoid multiple cancellations */
120 if ( ovp->ops->get_status( ovp ) != STATUS_PENDING )
122 ovp->ops->set_status ( ovp, STATUS_CANCELLED );
123 return __register_async ( ovp, STATUS_CANCELLED );
126 #endif /* __WINE_ASYNC_H */