Commit f507ccbf authored by Alexandre Julliard's avatar Alexandre Julliard

server: Specify the user APC to call only once the system APC has executed.

parent 7ec95c5b
...@@ -2302,7 +2302,7 @@ static void WINAPI read_changes_user_apc( void *arg, IO_STATUS_BLOCK *io, ULONG ...@@ -2302,7 +2302,7 @@ static void WINAPI read_changes_user_apc( void *arg, IO_STATUS_BLOCK *io, ULONG
RtlFreeHeap( GetProcessHeap(), 0, info ); RtlFreeHeap( GetProcessHeap(), 0, info );
} }
static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status, ULONG *total ) static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status, void **apc )
{ {
struct read_changes_info *info = user; struct read_changes_info *info = user;
char path[PATH_MAX]; char path[PATH_MAX];
...@@ -2347,7 +2347,8 @@ static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS st ...@@ -2347,7 +2347,8 @@ static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS st
} }
iosb->u.Status = ret; iosb->u.Status = ret;
iosb->Information = *total = len; iosb->Information = len;
*apc = read_changes_user_apc;
return ret; return ret;
} }
...@@ -2403,7 +2404,6 @@ NtNotifyChangeDirectoryFile( HANDLE FileHandle, HANDLE Event, ...@@ -2403,7 +2404,6 @@ NtNotifyChangeDirectoryFile( HANDLE FileHandle, HANDLE Event,
req->async.callback = read_changes_apc; req->async.callback = read_changes_apc;
req->async.iosb = IoStatusBlock; req->async.iosb = IoStatusBlock;
req->async.arg = info; req->async.arg = info;
req->async.apc = read_changes_user_apc;
req->async.event = wine_server_obj_handle( Event ); req->async.event = wine_server_obj_handle( Event );
req->async.cvalue = cvalue; req->async.cvalue = cvalue;
status = wine_server_call( req ); status = wine_server_call( req );
......
...@@ -334,7 +334,7 @@ NTSTATUS FILE_GetNtStatus(void) ...@@ -334,7 +334,7 @@ NTSTATUS FILE_GetNtStatus(void)
/*********************************************************************** /***********************************************************************
* FILE_AsyncReadService (INTERNAL) * FILE_AsyncReadService (INTERNAL)
*/ */
static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status, ULONG *total) static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status, void **apc)
{ {
async_fileio_read *fileio = user; async_fileio_read *fileio = user;
int fd, needs_close, result; int fd, needs_close, result;
...@@ -385,7 +385,8 @@ static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATU ...@@ -385,7 +385,8 @@ static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATU
if (status != STATUS_PENDING) if (status != STATUS_PENDING)
{ {
iosb->u.Status = status; iosb->u.Status = status;
iosb->Information = *total = fileio->already; iosb->Information = fileio->already;
*apc = fileio_apc;
} }
return status; return status;
} }
...@@ -659,7 +660,6 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent, ...@@ -659,7 +660,6 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
req->async.callback = FILE_AsyncReadService; req->async.callback = FILE_AsyncReadService;
req->async.iosb = io_status; req->async.iosb = io_status;
req->async.arg = fileio; req->async.arg = fileio;
req->async.apc = fileio_apc;
req->async.cvalue = cvalue; req->async.cvalue = cvalue;
status = wine_server_call( req ); status = wine_server_call( req );
} }
...@@ -812,7 +812,7 @@ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap ...@@ -812,7 +812,7 @@ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap
/*********************************************************************** /***********************************************************************
* FILE_AsyncWriteService (INTERNAL) * FILE_AsyncWriteService (INTERNAL)
*/ */
static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTATUS status, ULONG *total) static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTATUS status, void **apc)
{ {
async_fileio_write *fileio = user; async_fileio_write *fileio = user;
int result, fd, needs_close; int result, fd, needs_close;
...@@ -853,7 +853,8 @@ static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTAT ...@@ -853,7 +853,8 @@ static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTAT
if (status != STATUS_PENDING) if (status != STATUS_PENDING)
{ {
iosb->u.Status = status; iosb->u.Status = status;
iosb->Information = *total = fileio->already; iosb->Information = fileio->already;
*apc = fileio_apc;
} }
return status; return status;
} }
...@@ -983,7 +984,6 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent, ...@@ -983,7 +984,6 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
req->async.callback = FILE_AsyncWriteService; req->async.callback = FILE_AsyncWriteService;
req->async.iosb = io_status; req->async.iosb = io_status;
req->async.arg = fileio; req->async.arg = fileio;
req->async.apc = fileio_apc;
req->async.cvalue = cvalue; req->async.cvalue = cvalue;
status = wine_server_call( req ); status = wine_server_call( req );
} }
...@@ -1139,14 +1139,23 @@ NTSTATUS WINAPI NtWriteFileGather( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap ...@@ -1139,14 +1139,23 @@ NTSTATUS WINAPI NtWriteFileGather( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap
struct async_ioctl struct async_ioctl
{ {
HANDLE handle; /* handle to the device */ HANDLE handle; /* handle to the device */
HANDLE event; /* async event */
void *buffer; /* buffer for output */ void *buffer; /* buffer for output */
ULONG size; /* size of buffer */ ULONG size; /* size of buffer */
PIO_APC_ROUTINE apc; /* user apc params */ PIO_APC_ROUTINE apc; /* user apc params */
void *apc_arg; void *apc_arg;
}; };
/* callback for ioctl user APC */
static void WINAPI ioctl_apc( void *arg, IO_STATUS_BLOCK *io, ULONG reserved )
{
struct async_ioctl *async = arg;
if (async->apc) async->apc( async->apc_arg, io, reserved );
RtlFreeHeap( GetProcessHeap(), 0, async );
}
/* callback for ioctl async I/O completion */ /* callback for ioctl async I/O completion */
static NTSTATUS ioctl_completion( void *arg, IO_STATUS_BLOCK *io, NTSTATUS status, ULONG *total ) static NTSTATUS ioctl_completion( void *arg, IO_STATUS_BLOCK *io, NTSTATUS status, void **apc )
{ {
struct async_ioctl *async = arg; struct async_ioctl *async = arg;
...@@ -1158,22 +1167,18 @@ static NTSTATUS ioctl_completion( void *arg, IO_STATUS_BLOCK *io, NTSTATUS statu ...@@ -1158,22 +1167,18 @@ static NTSTATUS ioctl_completion( void *arg, IO_STATUS_BLOCK *io, NTSTATUS statu
req->user_arg = async; req->user_arg = async;
wine_server_set_reply( req, async->buffer, async->size ); wine_server_set_reply( req, async->buffer, async->size );
if (!(status = wine_server_call( req ))) if (!(status = wine_server_call( req )))
io->Information = *total = wine_server_reply_size( reply ); io->Information = wine_server_reply_size( reply );
} }
SERVER_END_REQ; SERVER_END_REQ;
} }
if (status != STATUS_PENDING) io->u.Status = status; if (status != STATUS_PENDING)
{
io->u.Status = status;
if (async->apc || async->event) *apc = ioctl_apc;
}
return status; return status;
} }
/* callback for ioctl user APC */
static void WINAPI ioctl_apc( void *arg, IO_STATUS_BLOCK *io, ULONG reserved )
{
struct async_ioctl *async = arg;
if (async->apc) async->apc( async->apc_arg, io, reserved );
RtlFreeHeap( GetProcessHeap(), 0, async );
}
/* do a ioctl call through the server */ /* do a ioctl call through the server */
static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event, static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event,
PIO_APC_ROUTINE apc, PVOID apc_context, PIO_APC_ROUTINE apc, PVOID apc_context,
...@@ -1190,6 +1195,7 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event, ...@@ -1190,6 +1195,7 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event,
if (!(async = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*async) ))) if (!(async = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*async) )))
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
async->handle = handle; async->handle = handle;
async->event = event;
async->buffer = out_buffer; async->buffer = out_buffer;
async->size = out_size; async->size = out_size;
async->apc = apc; async->apc = apc;
...@@ -1203,7 +1209,6 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event, ...@@ -1203,7 +1209,6 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event,
req->async.callback = ioctl_completion; req->async.callback = ioctl_completion;
req->async.iosb = io; req->async.iosb = io;
req->async.arg = async; req->async.arg = async;
req->async.apc = (apc || event) ? ioctl_apc : NULL;
req->async.event = wine_server_obj_handle( event ); req->async.event = wine_server_obj_handle( event );
req->async.cvalue = cvalue; req->async.cvalue = cvalue;
wine_server_add_data( req, in_buffer, in_size ); wine_server_add_data( req, in_buffer, in_size );
......
...@@ -865,12 +865,19 @@ static BOOL invoke_apc( const apc_call_t *call, apc_result_t *result ) ...@@ -865,12 +865,19 @@ static BOOL invoke_apc( const apc_call_t *call, apc_result_t *result )
break; break;
} }
case APC_ASYNC_IO: case APC_ASYNC_IO:
{
void *apc = NULL;
IO_STATUS_BLOCK *iosb = call->async_io.sb;
result->type = call->type; result->type = call->type;
result->async_io.status = call->async_io.func( call->async_io.user, result->async_io.status = call->async_io.func( call->async_io.user, iosb,
call->async_io.sb, call->async_io.status, &apc );
call->async_io.status, if (result->async_io.status != STATUS_PENDING)
&result->async_io.total ); {
result->async_io.total = iosb->Information;
result->async_io.apc = apc;
}
break; break;
}
case APC_VIRTUAL_ALLOC: case APC_VIRTUAL_ALLOC:
result->type = call->type; result->type = call->type;
addr = wine_server_get_ptr( call->virtual_alloc.addr ); addr = wine_server_get_ptr( call->virtual_alloc.addr );
......
...@@ -1127,7 +1127,7 @@ static int WS2_recv( int fd, struct ws2_async *wsa ) ...@@ -1127,7 +1127,7 @@ static int WS2_recv( int fd, struct ws2_async *wsa )
* *
* Handler for overlapped recv() operations. * Handler for overlapped recv() operations.
*/ */
static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status, ULONG *total ) static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status, void **apc)
{ {
ws2_async* wsa = user; ws2_async* wsa = user;
int result = 0, fd; int result = 0, fd;
...@@ -1163,7 +1163,8 @@ static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS stat ...@@ -1163,7 +1163,8 @@ static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS stat
if (status != STATUS_PENDING) if (status != STATUS_PENDING)
{ {
iosb->u.Status = status; iosb->u.Status = status;
iosb->Information = *total = result; iosb->Information = result;
*apc = ws2_async_apc;
} }
return status; return status;
} }
...@@ -1228,7 +1229,7 @@ static int WS2_send( int fd, struct ws2_async *wsa ) ...@@ -1228,7 +1229,7 @@ static int WS2_send( int fd, struct ws2_async *wsa )
* *
* Handler for overlapped send() operations. * Handler for overlapped send() operations.
*/ */
static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status, ULONG *total ) static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status, void **apc)
{ {
ws2_async* wsa = user; ws2_async* wsa = user;
int result = 0, fd; int result = 0, fd;
...@@ -1273,7 +1274,8 @@ static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS statu ...@@ -1273,7 +1274,8 @@ static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS statu
if (status != STATUS_PENDING) if (status != STATUS_PENDING)
{ {
iosb->u.Status = status; iosb->u.Status = status;
iosb->Information = *total = result; iosb->Information = result;
*apc = ws2_async_apc;
} }
return status; return status;
} }
...@@ -1283,7 +1285,7 @@ static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS statu ...@@ -1283,7 +1285,7 @@ static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS statu
* *
* Handler for shutdown() operations on overlapped sockets. * Handler for shutdown() operations on overlapped sockets.
*/ */
static NTSTATUS WS2_async_shutdown( void* user, PIO_STATUS_BLOCK iosb, NTSTATUS status, ULONG *total ) static NTSTATUS WS2_async_shutdown( void* user, PIO_STATUS_BLOCK iosb, NTSTATUS status, void **apc )
{ {
ws2_async* wsa = user; ws2_async* wsa = user;
int fd, err = 1; int fd, err = 1;
...@@ -1303,8 +1305,8 @@ static NTSTATUS WS2_async_shutdown( void* user, PIO_STATUS_BLOCK iosb, NTSTATUS ...@@ -1303,8 +1305,8 @@ static NTSTATUS WS2_async_shutdown( void* user, PIO_STATUS_BLOCK iosb, NTSTATUS
status = err ? wsaErrno() : STATUS_SUCCESS; status = err ? wsaErrno() : STATUS_SUCCESS;
break; break;
} }
*total = 0;
iosb->u.Status = status; iosb->u.Status = status;
*apc = ws2_async_apc;
return status; return status;
} }
...@@ -1335,7 +1337,6 @@ static int WS2_register_async_shutdown( SOCKET s, int type ) ...@@ -1335,7 +1337,6 @@ static int WS2_register_async_shutdown( SOCKET s, int type )
req->async.callback = WS2_async_shutdown; req->async.callback = WS2_async_shutdown;
req->async.iosb = &wsa->local_iosb; req->async.iosb = &wsa->local_iosb;
req->async.arg = wsa; req->async.arg = wsa;
req->async.apc = ws2_async_apc;
req->async.cvalue = 0; req->async.cvalue = 0;
status = wine_server_call( req ); status = wine_server_call( req );
} }
...@@ -2788,7 +2789,6 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, ...@@ -2788,7 +2789,6 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
req->async.callback = WS2_async_send; req->async.callback = WS2_async_send;
req->async.iosb = iosb; req->async.iosb = iosb;
req->async.arg = wsa; req->async.arg = wsa;
req->async.apc = ws2_async_apc;
req->async.event = wine_server_obj_handle( lpCompletionRoutine ? 0 : lpOverlapped->hEvent ); req->async.event = wine_server_obj_handle( lpCompletionRoutine ? 0 : lpOverlapped->hEvent );
req->async.cvalue = cvalue; req->async.cvalue = cvalue;
err = wine_server_call( req ); err = wine_server_call( req );
...@@ -4314,7 +4314,6 @@ INT WINAPI WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, ...@@ -4314,7 +4314,6 @@ INT WINAPI WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
req->async.callback = WS2_async_recv; req->async.callback = WS2_async_recv;
req->async.iosb = iosb; req->async.iosb = iosb;
req->async.arg = wsa; req->async.arg = wsa;
req->async.apc = ws2_async_apc;
req->async.event = wine_server_obj_handle( lpCompletionRoutine ? 0 : lpOverlapped->hEvent ); req->async.event = wine_server_obj_handle( lpCompletionRoutine ? 0 : lpOverlapped->hEvent );
req->async.cvalue = cvalue; req->async.cvalue = cvalue;
err = wine_server_call( req ); err = wine_server_call( req );
......
...@@ -169,7 +169,6 @@ typedef struct ...@@ -169,7 +169,6 @@ typedef struct
void *callback; void *callback;
void *iosb; void *iosb;
void *arg; void *arg;
void *apc;
apc_param_t cvalue; apc_param_t cvalue;
} async_data_t; } async_data_t;
...@@ -287,7 +286,7 @@ typedef union ...@@ -287,7 +286,7 @@ typedef union
struct struct
{ {
enum apc_type type; enum apc_type type;
unsigned int (*func)(void*, void*, unsigned int, unsigned int *); unsigned int (*func)(void*, void*, unsigned int, void **);
void *user; void *user;
void *sb; void *sb;
unsigned int status; unsigned int status;
...@@ -377,6 +376,7 @@ typedef union ...@@ -377,6 +376,7 @@ typedef union
{ {
enum apc_type type; enum apc_type type;
unsigned int status; unsigned int status;
void *apc;
unsigned int total; unsigned int total;
} async_io; } async_io;
struct struct
...@@ -5060,6 +5060,6 @@ union generic_reply ...@@ -5060,6 +5060,6 @@ union generic_reply
struct set_window_layered_info_reply set_window_layered_info_reply; struct set_window_layered_info_reply set_window_layered_info_reply;
}; };
#define SERVER_PROTOCOL_VERSION 371 #define SERVER_PROTOCOL_VERSION 372
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -234,7 +234,7 @@ void async_set_timeout( struct async *async, timeout_t timeout, unsigned int sta ...@@ -234,7 +234,7 @@ void async_set_timeout( struct async *async, timeout_t timeout, unsigned int sta
} }
/* store the result of the client-side async callback */ /* store the result of the client-side async callback */
void async_set_result( struct object *obj, unsigned int status, unsigned int total ) void async_set_result( struct object *obj, unsigned int status, unsigned int total, void *apc )
{ {
struct async *async = (struct async *)obj; struct async *async = (struct async *)obj;
...@@ -260,12 +260,12 @@ void async_set_result( struct object *obj, unsigned int status, unsigned int tot ...@@ -260,12 +260,12 @@ void async_set_result( struct object *obj, unsigned int status, unsigned int tot
async->status = status; async->status = status;
if (async->completion && async->data.cvalue) if (async->completion && async->data.cvalue)
add_completion( async->completion, async->comp_key, async->data.cvalue, status, total ); add_completion( async->completion, async->comp_key, async->data.cvalue, status, total );
if (async->data.apc) if (apc)
{ {
apc_call_t data; apc_call_t data;
memset( &data, 0, sizeof(data) ); memset( &data, 0, sizeof(data) );
data.type = APC_USER; data.type = APC_USER;
data.user.func = async->data.apc; data.user.func = apc;
data.user.args[0] = (apc_param_t)(unsigned long)async->data.arg; data.user.args[0] = (apc_param_t)(unsigned long)async->data.arg;
data.user.args[1] = (apc_param_t)(unsigned long)async->data.iosb; data.user.args[1] = (apc_param_t)(unsigned long)async->data.iosb;
data.user.args[2] = 0; data.user.args[2] = 0;
......
...@@ -138,7 +138,7 @@ extern void free_async_queue( struct async_queue *queue ); ...@@ -138,7 +138,7 @@ extern void free_async_queue( struct async_queue *queue );
extern struct async *create_async( struct thread *thread, struct async_queue *queue, extern struct async *create_async( struct thread *thread, struct async_queue *queue,
const async_data_t *data ); const async_data_t *data );
extern void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status ); extern void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status );
extern void async_set_result( struct object *obj, unsigned int status, unsigned int total ); extern void async_set_result( struct object *obj, unsigned int status, unsigned int total, void *apc );
extern int async_waiting( struct async_queue *queue ); extern int async_waiting( struct async_queue *queue );
extern void async_terminate( struct async *async, unsigned int status ); extern void async_terminate( struct async *async, unsigned int status );
extern void async_wake_up( struct async_queue *queue, unsigned int status ); extern void async_wake_up( struct async_queue *queue, unsigned int status );
......
...@@ -185,7 +185,6 @@ typedef struct ...@@ -185,7 +185,6 @@ typedef struct
void *callback; /* client-side callback to call upon end of async */ void *callback; /* client-side callback to call upon end of async */
void *iosb; /* I/O status block in client addr space */ void *iosb; /* I/O status block in client addr space */
void *arg; /* opaque user data to pass to callback */ void *arg; /* opaque user data to pass to callback */
void *apc; /* user apc to call */
apc_param_t cvalue; /* completion value to use for completion events */ apc_param_t cvalue; /* completion value to use for completion events */
} async_data_t; } async_data_t;
...@@ -303,7 +302,7 @@ typedef union ...@@ -303,7 +302,7 @@ typedef union
struct struct
{ {
enum apc_type type; /* APC_ASYNC_IO */ enum apc_type type; /* APC_ASYNC_IO */
unsigned int (*func)(void*, void*, unsigned int, unsigned int *); unsigned int (*func)(void*, void*, unsigned int, void **);
void *user; /* user pointer */ void *user; /* user pointer */
void *sb; /* status block */ void *sb; /* status block */
unsigned int status; /* I/O status */ unsigned int status; /* I/O status */
...@@ -393,6 +392,7 @@ typedef union ...@@ -393,6 +392,7 @@ typedef union
{ {
enum apc_type type; /* APC_ASYNC_IO */ enum apc_type type; /* APC_ASYNC_IO */
unsigned int status; /* new status of async operation */ unsigned int status; /* new status of async operation */
void *apc; /* user APC to call */
unsigned int total; /* bytes transferred */ unsigned int total; /* bytes transferred */
} async_io; } async_io;
struct struct
......
...@@ -1196,7 +1196,9 @@ DECL_HANDLER(select) ...@@ -1196,7 +1196,9 @@ DECL_HANDLER(select)
} }
else if (apc->result.type == APC_ASYNC_IO) else if (apc->result.type == APC_ASYNC_IO)
{ {
if (apc->owner) async_set_result( apc->owner, apc->result.async_io.status, apc->result.async_io.total ); if (apc->owner)
async_set_result( apc->owner, apc->result.async_io.status,
apc->result.async_io.total, apc->result.async_io.apc );
} }
wake_up( &apc->obj, 0 ); wake_up( &apc->obj, 0 );
close_handle( current->process, req->prev_apc ); close_handle( current->process, req->prev_apc );
......
...@@ -218,8 +218,8 @@ static void dump_apc_result( const apc_result_t *result ) ...@@ -218,8 +218,8 @@ static void dump_apc_result( const apc_result_t *result )
case APC_NONE: case APC_NONE:
break; break;
case APC_ASYNC_IO: case APC_ASYNC_IO:
fprintf( stderr, "APC_ASYNC_IO,status=%s", fprintf( stderr, "APC_ASYNC_IO,status=%s,total=%u,apc=%p",
get_status_name( result->async_io.status ) ); get_status_name( result->async_io.status ), result->async_io.total, result->async_io.apc );
break; break;
case APC_VIRTUAL_ALLOC: case APC_VIRTUAL_ALLOC:
fprintf( stderr, "APC_VIRTUAL_ALLOC,status=%s,addr=", fprintf( stderr, "APC_VIRTUAL_ALLOC,status=%s,addr=",
...@@ -301,9 +301,10 @@ static void dump_apc_result( const apc_result_t *result ) ...@@ -301,9 +301,10 @@ static void dump_apc_result( const apc_result_t *result )
static void dump_async_data( const async_data_t *data ) static void dump_async_data( const async_data_t *data )
{ {
fprintf( stderr, "{handle=%04x,event=%04x,callback=%p,iosb=%p,arg=%p,apc=%p,cvalue=}", fprintf( stderr, "{handle=%04x,event=%04x,callback=%p,iosb=%p,arg=%p,cvalue=",
data->handle, data->event, data->callback, data->iosb, data->arg, data->apc ); data->handle, data->event, data->callback, data->iosb, data->arg );
dump_uint64( &data->cvalue ); dump_uint64( &data->cvalue );
fputc( '}', stderr );
} }
static void dump_luid( const luid_t *luid ) static void dump_luid( const luid_t *luid )
......
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