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
31 #include <wine/server.h>
36 typedef void (*async_handler
)(struct async_private
*ovp
);
37 typedef void (CALLBACK
*async_call_completion_func
)(ULONG_PTR data
);
38 typedef DWORD (*async_get_count
)(const struct async_private
*ovp
);
39 typedef void (*async_cleanup
)(struct async_private
*ovp
);
41 typedef struct async_ops
43 async_get_count get_count
;
44 async_call_completion_func call_completion
;
45 async_cleanup cleanup
;
48 typedef struct async_private
50 struct async_ops
* ops
;
56 IO_STATUS_BLOCK
* iosb
;
57 struct async_private
* next
;
58 struct async_private
* prev
;
61 /* All functions declared static for Dll separation purposes */
62 static void CALLBACK
call_user_apc( ULONG_PTR arg1
, ULONG_PTR arg2
, ULONG_PTR arg3
)
64 PAPCFUNC func
= (PAPCFUNC
)arg1
;
68 inline static void finish_async( async_private
*ovp
)
71 ovp
->prev
->next
= ovp
->next
;
73 NtCurrentTeb()->pending_list
= ovp
->next
;
76 ovp
->next
->prev
= ovp
->prev
;
78 ovp
->next
= ovp
->prev
= NULL
;
81 if ( ovp
->event
!= INVALID_HANDLE_VALUE
)
82 NtSetEvent( ovp
->event
, NULL
);
84 if ( ovp
->ops
->call_completion
)
85 NtQueueApcThread( GetCurrentThread(), call_user_apc
,
86 (ULONG_PTR
)ovp
->ops
->call_completion
, (ULONG_PTR
)ovp
, 0 );
88 ovp
->ops
->cleanup( ovp
);
91 inline static NTSTATUS
__register_async( async_private
*ovp
, const DWORD status
)
95 SERVER_START_REQ( register_async
)
97 req
->handle
= ovp
->handle
;
98 req
->overlapped
= ovp
;
99 req
->type
= ovp
->type
;
100 req
->count
= ovp
->ops
->get_count( ovp
);
101 req
->status
= status
;
102 ret
= wine_server_call( req
);
106 if (ret
) ovp
->iosb
->u
.Status
= ret
;
108 if ( ovp
->iosb
->u
.Status
!= STATUS_PENDING
)
114 #define register_old_async(ovp) \
115 __register_async(ovp, ovp->iosb->u.Status);
117 inline static NTSTATUS
register_new_async( async_private
*ovp
)
119 ovp
->iosb
->u
.Status
= STATUS_PENDING
;
121 ovp
->next
= NtCurrentTeb()->pending_list
;
123 if ( ovp
->next
) ovp
->next
->prev
= ovp
;
124 NtCurrentTeb()->pending_list
= ovp
;
126 return __register_async( ovp
, STATUS_PENDING
);
129 inline static NTSTATUS
cancel_async( async_private
*ovp
)
131 /* avoid multiple cancellations */
132 if ( ovp
->iosb
->u
.Status
!= STATUS_PENDING
)
133 return STATUS_SUCCESS
;
134 ovp
->iosb
->u
.Status
= STATUS_CANCELLED
;
135 return __register_async( ovp
, STATUS_CANCELLED
);
138 #endif /* __WINE_ASYNC_H */