Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/ntdll/unix/file.c | 92 ++++++++++++------------- dlls/ntdll/unix/server.c | 6 +- dlls/ntdll/unix/socket.c | 104 +++++++++++++---------------- dlls/ntdll/unix/unix_private.h | 3 +- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 50 +++++--------- 5 files changed, 112 insertions(+), 143 deletions(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 5da9ca560f6..bcd74c9d6aa 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -4679,34 +4679,34 @@ struct async_fileio *alloc_fileio( DWORD size, async_callback_t callback, HANDLE }
/* callback for irp async I/O completion */ -static NTSTATUS irp_completion( void *user, ULONG_PTR *info, NTSTATUS status ) +static BOOL irp_completion( void *user, ULONG_PTR *info, NTSTATUS *status ) { struct async_irp *async = user;
- if (status == STATUS_ALERTED) + if (*status == STATUS_ALERTED) { SERVER_START_REQ( get_async_result ) { req->user_arg = wine_server_client_ptr( async ); wine_server_set_reply( req, async->buffer, async->size ); - status = virtual_locked_server_call( req ); + *status = virtual_locked_server_call( req ); } SERVER_END_REQ; } - if (status != STATUS_PENDING) release_fileio( &async->io ); - return status; + release_fileio( &async->io ); + return TRUE; }
-static NTSTATUS async_read_proc( void *user, ULONG_PTR *info, NTSTATUS status ) +static BOOL async_read_proc( void *user, ULONG_PTR *info, NTSTATUS *status ) { struct async_fileio_read *fileio = user; int fd, needs_close, result;
- switch (status) + switch (*status) { case STATUS_ALERTED: /* got some new data */ /* check to see if the data is ready (non-blocking) */ - if ((status = server_get_unix_fd( fileio->io.handle, FILE_READ_DATA, &fd, + if ((*status = server_get_unix_fd( fileio->io.handle, FILE_READ_DATA, &fd, &needs_close, NULL, NULL ))) break;
@@ -4716,48 +4716,48 @@ static NTSTATUS async_read_proc( void *user, ULONG_PTR *info, NTSTATUS status ) if (result < 0) { if (errno == EAGAIN || errno == EINTR) - status = STATUS_PENDING; - else /* check to see if the transfer is complete */ - status = errno_to_status( errno ); + return FALSE; + + /* check to see if the transfer is complete */ + *status = errno_to_status( errno ); } else if (result == 0) { - status = fileio->already ? STATUS_SUCCESS : STATUS_PIPE_BROKEN; + *status = fileio->already ? STATUS_SUCCESS : STATUS_PIPE_BROKEN; } else { fileio->already += result; - if (fileio->already >= fileio->count || fileio->avail_mode) - status = STATUS_SUCCESS; - else - status = STATUS_PENDING; + + if (fileio->already < fileio->count && !fileio->avail_mode) + return FALSE; + + *status = STATUS_SUCCESS; } break;
case STATUS_TIMEOUT: case STATUS_IO_TIMEOUT: - if (fileio->already) status = STATUS_SUCCESS; + if (fileio->already) *status = STATUS_SUCCESS; break; } - if (status != STATUS_PENDING) - { - *info = fileio->already; - release_fileio( &fileio->io ); - } - return status; + + *info = fileio->already; + release_fileio( &fileio->io ); + return TRUE; }
-static NTSTATUS async_write_proc( void *user, ULONG_PTR *info, NTSTATUS status ) +static BOOL async_write_proc( void *user, ULONG_PTR *info, NTSTATUS *status ) { struct async_fileio_write *fileio = user; int result, fd, needs_close; enum server_fd_type type;
- switch (status) + switch (*status) { case STATUS_ALERTED: /* write some data (non-blocking) */ - if ((status = server_get_unix_fd( fileio->io.handle, FILE_WRITE_DATA, &fd, + if ((*status = server_get_unix_fd( fileio->io.handle, FILE_WRITE_DATA, &fd, &needs_close, &type, NULL ))) break;
@@ -4770,27 +4770,26 @@ static NTSTATUS async_write_proc( void *user, ULONG_PTR *info, NTSTATUS status )
if (result < 0) { - if (errno == EAGAIN || errno == EINTR) status = STATUS_PENDING; - else status = errno_to_status( errno ); + if (errno == EAGAIN || errno == EINTR) return FALSE; + *status = errno_to_status( errno ); } else { fileio->already += result; - status = (fileio->already < fileio->count) ? STATUS_PENDING : STATUS_SUCCESS; + if (fileio->already < fileio->count) return FALSE; + *status = STATUS_SUCCESS; } break;
case STATUS_TIMEOUT: case STATUS_IO_TIMEOUT: - if (fileio->already) status = STATUS_SUCCESS; + if (fileio->already) *status = STATUS_SUCCESS; break; } - if (status != STATUS_PENDING) - { - *info = fileio->already; - release_fileio( &fileio->io ); - } - return status; + + *info = fileio->already; + release_fileio( &fileio->io ); + return TRUE; }
/* do a read call through the server */ @@ -6054,23 +6053,23 @@ NTSTATUS WINAPI NtUnlockFile( HANDLE handle, IO_STATUS_BLOCK *io_status, LARGE_I }
-static NTSTATUS read_changes_apc( void *user, ULONG_PTR *info, NTSTATUS status ) +static BOOL read_changes_apc( void *user, ULONG_PTR *info, NTSTATUS *status ) { struct async_fileio_read_changes *fileio = user; int size = 0;
- if (status == STATUS_ALERTED) + if (*status == STATUS_ALERTED) { SERVER_START_REQ( read_change ) { req->handle = wine_server_obj_handle( fileio->io.handle ); wine_server_set_reply( req, fileio->data, fileio->data_size ); - status = wine_server_call( req ); + *status = wine_server_call( req ); size = wine_server_reply_size( reply ); } SERVER_END_REQ;
- if (status == STATUS_SUCCESS && fileio->buffer) + if (*status == STATUS_SUCCESS && fileio->buffer) { FILE_NOTIFY_INFORMATION *pfni = fileio->buffer; int i, left = fileio->buffer_size; @@ -6105,7 +6104,7 @@ static NTSTATUS read_changes_apc( void *user, ULONG_PTR *info, NTSTATUS status )
if (size) { - status = STATUS_NOTIFY_ENUM_DIR; + *status = STATUS_NOTIFY_ENUM_DIR; size = 0; } else @@ -6116,17 +6115,14 @@ static NTSTATUS read_changes_apc( void *user, ULONG_PTR *info, NTSTATUS status ) } else { - status = STATUS_NOTIFY_ENUM_DIR; + *status = STATUS_NOTIFY_ENUM_DIR; size = 0; } }
- if (status != STATUS_PENDING) - { - *info = size; - release_fileio( &fileio->io ); - } - return status; + *info = size; + release_fileio( &fileio->io ); + return TRUE; }
#define FILE_NOTIFY_ALL ( \ diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index 08733fba710..050824a1440 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -379,11 +379,13 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOO { struct async_fileio *user = wine_server_get_ptr( call->async_io.user ); ULONG_PTR info = call->async_io.result; + NTSTATUS status;
result->type = call->type; - result->async_io.status = user->callback( user, &info, call->async_io.status ); - if (result->async_io.status != STATUS_PENDING) + status = call->async_io.status; + if (user->callback( user, &info, &status )) { + result->async_io.status = status; result->async_io.total = info; /* the server will pass us NULL if a call failed synchronously */ set_async_iosb( call->async_io.sb, result->async_io.status, info ); diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c index db58d2e5b12..73d61c0d4e6 100644 --- a/dlls/ntdll/unix/socket.c +++ b/dlls/ntdll/unix/socket.c @@ -562,28 +562,27 @@ static NTSTATUS try_recv( int fd, struct async_recv_ioctl *async, ULONG_PTR *siz return status; }
-static NTSTATUS async_recv_proc( void *user, ULONG_PTR *info, NTSTATUS status ) +static BOOL async_recv_proc( void *user, ULONG_PTR *info, NTSTATUS *status ) { struct async_recv_ioctl *async = user; int fd, needs_close;
- TRACE( "%#x\n", status ); + TRACE( "%#x\n", *status );
- if (status == STATUS_ALERTED) + if (*status == STATUS_ALERTED) { - if ((status = server_get_unix_fd( async->io.handle, 0, &fd, &needs_close, NULL, NULL ))) - return status; - - status = try_recv( fd, async, info ); - TRACE( "got status %#x, %#lx bytes read\n", status, *info ); - - if (status == STATUS_DEVICE_NOT_READY) - status = STATUS_PENDING; + if ((*status = server_get_unix_fd( async->io.handle, 0, &fd, &needs_close, NULL, NULL ))) + return TRUE;
+ *status = try_recv( fd, async, info ); + TRACE( "got status %#x, %#lx bytes read\n", *status, *info ); if (needs_close) close( fd ); + + if (*status == STATUS_DEVICE_NOT_READY) + return FALSE; } - if (status != STATUS_PENDING) release_fileio( &async->io ); - return status; + release_fileio( &async->io ); + return TRUE; }
static NTSTATUS sock_recv( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user, IO_STATUS_BLOCK *io, @@ -696,29 +695,26 @@ static ULONG_PTR fill_poll_output( struct async_poll_ioctl *async, NTSTATUS stat return offsetof( struct afd_poll_params, sockets[count] ); }
-static NTSTATUS async_poll_proc( void *user, ULONG_PTR *info, NTSTATUS status ) +static BOOL async_poll_proc( void *user, ULONG_PTR *info, NTSTATUS *status ) { struct async_poll_ioctl *async = user;
- if (status == STATUS_ALERTED) + if (*status == STATUS_ALERTED) { SERVER_START_REQ( get_async_result ) { req->user_arg = wine_server_client_ptr( async ); wine_server_set_reply( req, async->sockets, async->count * sizeof(async->sockets[0]) ); - status = wine_server_call( req ); + *status = wine_server_call( req ); } SERVER_END_REQ;
- *info = fill_poll_output( async, status ); + *info = fill_poll_output( async, *status ); }
- if (status != STATUS_PENDING) - { - free( async->input ); - release_fileio( &async->io ); - } - return status; + free( async->input ); + release_fileio( &async->io ); + return TRUE; }
@@ -877,32 +873,29 @@ static NTSTATUS try_send( int fd, struct async_send_ioctl *async ) return STATUS_SUCCESS; }
-static NTSTATUS async_send_proc( void *user, ULONG_PTR *info, NTSTATUS status ) +static BOOL async_send_proc( void *user, ULONG_PTR *info, NTSTATUS *status ) { struct async_send_ioctl *async = user; int fd, needs_close;
- TRACE( "%#x\n", status ); + TRACE( "%#x\n", *status );
- if (status == STATUS_ALERTED) + if (*status == STATUS_ALERTED) { - if ((status = server_get_unix_fd( async->io.handle, 0, &fd, &needs_close, NULL, NULL ))) - return status; + if ((*status = server_get_unix_fd( async->io.handle, 0, &fd, &needs_close, NULL, NULL ))) + return TRUE;
- status = try_send( fd, async ); - TRACE( "got status %#x\n", status ); - - if (status == STATUS_DEVICE_NOT_READY) - status = STATUS_PENDING; + *status = try_send( fd, async ); + TRACE( "got status %#x\n", *status );
if (needs_close) close( fd ); + + if (*status == STATUS_DEVICE_NOT_READY) + return FALSE; } - if (status != STATUS_PENDING) - { - *info = async->sent_len; - release_fileio( &async->io ); - } - return status; + *info = async->sent_len; + release_fileio( &async->io ); + return TRUE; }
static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user, @@ -1040,39 +1033,36 @@ static NTSTATUS try_transmit( int sock_fd, int file_fd, struct async_transmit_io return STATUS_SUCCESS; }
-static NTSTATUS async_transmit_proc( void *user, ULONG_PTR *info, NTSTATUS status ) +static BOOL async_transmit_proc( void *user, ULONG_PTR *info, NTSTATUS *status ) { int sock_fd, file_fd = -1, sock_needs_close = FALSE, file_needs_close = FALSE; struct async_transmit_ioctl *async = user;
- TRACE( "%#x\n", status ); + TRACE( "%#x\n", *status );
- if (status == STATUS_ALERTED) + if (*status == STATUS_ALERTED) { - if ((status = server_get_unix_fd( async->io.handle, 0, &sock_fd, &sock_needs_close, NULL, NULL ))) - return status; + if ((*status = server_get_unix_fd( async->io.handle, 0, &sock_fd, &sock_needs_close, NULL, NULL ))) + return TRUE;
- if (async->file && (status = server_get_unix_fd( async->file, 0, &file_fd, &file_needs_close, NULL, NULL ))) + if (async->file && (*status = server_get_unix_fd( async->file, 0, &file_fd, &file_needs_close, NULL, NULL ))) { if (sock_needs_close) close( sock_fd ); - return status; + return TRUE; }
- status = try_transmit( sock_fd, file_fd, async ); - TRACE( "got status %#x\n", status ); - - if (status == STATUS_DEVICE_NOT_READY) - status = STATUS_PENDING; + *status = try_transmit( sock_fd, file_fd, async ); + TRACE( "got status %#x\n", *status );
if (sock_needs_close) close( sock_fd ); if (file_needs_close) close( file_fd ); + + if (*status == STATUS_DEVICE_NOT_READY) + return FALSE; } - if (status != STATUS_PENDING) - { - *info = async->head_cursor + async->file_cursor + async->tail_cursor; - release_fileio( &async->io ); - } - return status; + *info = async->head_cursor + async->file_cursor + async->tail_cursor; + release_fileio( &async->io ); + return TRUE; }
static NTSTATUS sock_transmit( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user, diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index fb1a4a397e9..6b8835bcba0 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -70,7 +70,8 @@ static inline struct ntdll_thread_data *ntdll_get_thread_data(void) return (struct ntdll_thread_data *)&NtCurrentTeb()->GdiTebBatch; }
-typedef NTSTATUS async_callback_t( void *user, ULONG_PTR *info, NTSTATUS status ); +/* returns TRUE if the async is complete; FALSE if it should be restarted */ +typedef BOOL async_callback_t( void *user, ULONG_PTR *info, NTSTATUS *status );
struct async_fileio { diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 2484479efc3..00daccb8487 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -677,7 +677,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) if (NT_ERROR(expect_status)) ok(size == 0xdeadf00d, "got size %u\n", size); else if (!NT_ERROR(params->iosb_status)) - todo_wine_if (params->iosb_status == STATUS_PENDING) ok(size == 3, "got size %u\n", size); + ok(size == 3, "got size %u\n", size); /* size is garbage if !NT_ERROR(expect_status) && NT_ERROR(iosb_status) */ ok(!strcmp(buffer, expect_buffer), "got buffer %s\n", buffer);
@@ -694,11 +694,8 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) } else { - todo_wine_if (params->iosb_status == STATUS_PENDING) - { - ok(io.Status == params->iosb_status, "got %#x\n", io.Status); - ok(io.Information == 3, "got size %Iu\n", io.Information); - } + ok(io.Status == params->iosb_status, "got %#x\n", io.Status); + ok(io.Information == 3, "got size %Iu\n", io.Information); } ok(!strcmp(buffer, expect_buffer), "got buffer %s\n", buffer);
@@ -731,11 +728,8 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) } else { - todo_wine_if (params->iosb_status == STATUS_PENDING) - { - ok(io.Status == params->iosb_status, "got %#x\n", io.Status); - ok(io.Information == 3, "got size %Iu\n", io.Information); - } + ok(io.Status == params->iosb_status, "got %#x\n", io.Status); + ok(io.Information == 3, "got size %Iu\n", io.Information); ret = WaitForSingleObject(event, 0); ok(!ret, "got %d\n", ret); } @@ -758,8 +752,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ok(key == 123, "got key %Iu\n", key); ok(value == 456, "got value %Iu\n", value); ok(io.Status == params->iosb_status, "got iosb status %#x\n", io.Status); - todo_wine_if (params->iosb_status == STATUS_PENDING) - ok(io.Information == 3, "got information %Iu\n", io.Information); + ok(io.Information == 3, "got information %Iu\n", io.Information); }
/* As above, but set the event first, to show that the event is always @@ -782,11 +775,8 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) } else { - todo_wine_if (params->iosb_status == STATUS_PENDING) - { - ok(io.Status == params->iosb_status, "got %#x\n", io.Status); - ok(io.Information == 3, "got size %Iu\n", io.Information); - } + ok(io.Status == params->iosb_status, "got %#x\n", io.Status); + ok(io.Information == 3, "got size %Iu\n", io.Information); ret = WaitForSingleObject(event, 0); ok(!ret, "got %d\n", ret); } @@ -813,11 +803,8 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) } else { - todo_wine_if (params->iosb_status == STATUS_PENDING) - { - ok(io.Status == params->iosb_status, "got %#x\n", io.Status); - ok(io.Information == 3, "got size %Iu\n", io.Information); - } + ok(io.Status == params->iosb_status, "got %#x\n", io.Status); + ok(io.Information == 3, "got size %Iu\n", io.Information); ret = WaitForSingleObject(file, 0); ok(!ret, "got %d\n", ret); } @@ -848,11 +835,8 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) } else { - todo_wine_if (params->iosb_status == STATUS_PENDING) - { - ok(io.Status == params->iosb_status, "got %#x\n", io.Status); - ok(io.Information == 3, "got size %Iu\n", io.Information); - } + ok(io.Status == params->iosb_status, "got %#x\n", io.Status); + ok(io.Information == 3, "got size %Iu\n", io.Information); ret = WaitForSingleObject(event, 0); ok(!ret, "got %d\n", ret); } @@ -883,8 +867,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ok(key == 123, "got key %Iu\n", key); ok(value == 456, "got value %Iu\n", value); ok(io.Status == params->iosb_status, "got iosb status %#x\n", io.Status); - todo_wine_if (params->iosb_status == STATUS_PENDING) - ok(io.Information == 3, "got information %Iu\n", io.Information); + ok(io.Information == 3, "got information %Iu\n", io.Information); } }
@@ -914,11 +897,8 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) } else { - todo_wine_if (params->iosb_status == STATUS_PENDING) - { - ok(io.Status == params->iosb_status, "got %#x\n", io.Status); - ok(io.Information == 3, "got size %Iu\n", io.Information); - } + ok(io.Status == params->iosb_status, "got %#x\n", io.Status); + ok(io.Information == 3, "got size %Iu\n", io.Information); } ok(!strcmp(buffer, expect_buffer), "got buffer %s\n", buffer);