From 6dcb280bc5a36b7ddac69b4cdbb84dd2b4e041d1 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 10 Apr 2007 17:19:24 +0200 Subject: [PATCH] ntdll: Simplify the async read/write code now that most of the work is done in the server. --- dlls/ntdll/file.c | 121 ++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 58 deletions(-) diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index f3ba690fcfe..078e4fe4941 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -236,57 +236,24 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB /*********************************************************************** * Asynchronous file I/O * */ -static NTSTATUS FILE_AsyncReadService(void*, PIO_STATUS_BLOCK, NTSTATUS); -static NTSTATUS FILE_AsyncWriteService(void*, PIO_STATUS_BLOCK, NTSTATUS); -typedef struct async_fileio +typedef struct { HANDLE handle; - PIO_APC_ROUTINE apc; - void* apc_user; char* buffer; unsigned int already; unsigned int count; BOOL avail_mode; - HANDLE event; -} async_fileio; +} async_fileio_read; -static void fileio_terminate(async_fileio *fileio, IO_STATUS_BLOCK* iosb, NTSTATUS status) +typedef struct { - TRACE("data: %p\n", fileio); + HANDLE handle; + const char *buffer; + unsigned int already; + unsigned int count; +} async_fileio_write; - iosb->u.Status = status; - iosb->Information = fileio->already; - RtlFreeHeap( GetProcessHeap(), 0, fileio ); -} - - -static ULONG fileio_queue_async(async_fileio* fileio, IO_STATUS_BLOCK* iosb, - BOOL do_read) -{ - NTSTATUS status; - - SERVER_START_REQ( register_async ) - { - req->handle = fileio->handle; - req->async.callback = do_read ? FILE_AsyncReadService : FILE_AsyncWriteService; - req->async.iosb = iosb; - req->async.arg = fileio; - req->async.apc = fileio->apc; - req->async.apc_arg = fileio->apc_user; - req->async.event = fileio->event; - req->type = do_read ? ASYNC_TYPE_READ : ASYNC_TYPE_WRITE; - req->count = (fileio->count < fileio->already) ? 0 : fileio->count - fileio->already; - status = wine_server_call( req ); - } - SERVER_END_REQ; - - if (status != STATUS_PENDING) - fileio_terminate( fileio, iosb, status ); - else - NtCurrentTeb()->num_async_io++; - return status; -} /*********************************************************************** * FILE_GetNtStatus(void) @@ -339,7 +306,7 @@ NTSTATUS FILE_GetNtStatus(void) */ static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status) { - async_fileio *fileio = (async_fileio*)user; + async_fileio_read *fileio = user; int fd, needs_close, result; TRACE("%p %p 0x%x\n", iosb, fileio->buffer, status); @@ -394,7 +361,12 @@ static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATU if (fileio->already) status = STATUS_SUCCESS; break; } - if (status != STATUS_PENDING) fileio_terminate(fileio, iosb, status); + if (status != STATUS_PENDING) + { + iosb->u.Status = status; + iosb->Information = fileio->already; + RtlFreeHeap( GetProcessHeap(), 0, fileio ); + } return status; } @@ -580,7 +552,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent, if (flags & FD_FLAG_OVERLAPPED) { - async_fileio *fileio; + async_fileio_read *fileio; if (total && (flags & FD_FLAG_AVAILABLE)) { @@ -588,7 +560,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent, goto done; } - if (!(fileio = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(async_fileio)))) + if (!(fileio = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(*fileio)))) { status = STATUS_NO_MEMORY; goto done; @@ -596,12 +568,26 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent, fileio->handle = hFile; fileio->already = total; fileio->count = length; - fileio->apc = apc; - fileio->apc_user = apc_user; fileio->buffer = buffer; fileio->avail_mode = (flags & FD_FLAG_AVAILABLE); - fileio->event = hEvent; - status = fileio_queue_async(fileio, io_status, TRUE); + + SERVER_START_REQ( register_async ) + { + req->handle = hFile; + req->type = ASYNC_TYPE_READ; + req->count = length; + req->async.callback = FILE_AsyncReadService; + req->async.iosb = io_status; + req->async.arg = fileio; + req->async.apc = apc; + req->async.apc_arg = apc_user; + req->async.event = hEvent; + status = wine_server_call( req ); + } + SERVER_END_REQ; + + if (status != STATUS_PENDING) RtlFreeHeap( GetProcessHeap(), 0, fileio ); + else NtCurrentTeb()->num_async_io++; goto done; } else /* synchronous read, wait for the fd to become ready */ @@ -662,7 +648,7 @@ done: */ static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTATUS status) { - async_fileio *fileio = user; + async_fileio_write *fileio = user; int result, fd, needs_close; enum server_fd_type type; @@ -701,7 +687,12 @@ static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTAT if (fileio->already) status = STATUS_SUCCESS; break; } - if (status != STATUS_PENDING) fileio_terminate(fileio, iosb, status); + if (status != STATUS_PENDING) + { + iosb->u.Status = status; + iosb->Information = fileio->already; + RtlFreeHeap( GetProcessHeap(), 0, fileio ); + } return status; } @@ -799,9 +790,9 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent, if (flags & FD_FLAG_OVERLAPPED) { - async_fileio *fileio; + async_fileio_write *fileio; - if (!(fileio = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(async_fileio)))) + if (!(fileio = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(*fileio)))) { status = STATUS_NO_MEMORY; goto done; @@ -809,11 +800,25 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent, fileio->handle = hFile; fileio->already = total; fileio->count = length; - fileio->apc = apc; - fileio->apc_user = apc_user; - fileio->buffer = (void*)buffer; - fileio->event = hEvent; - status = fileio_queue_async(fileio, io_status, FALSE); + fileio->buffer = buffer; + + SERVER_START_REQ( register_async ) + { + req->handle = hFile; + req->type = ASYNC_TYPE_WRITE; + req->count = length; + req->async.callback = FILE_AsyncWriteService; + req->async.iosb = io_status; + req->async.arg = fileio; + req->async.apc = apc; + req->async.apc_arg = apc_user; + req->async.event = hEvent; + status = wine_server_call( req ); + } + SERVER_END_REQ; + + if (status != STATUS_PENDING) RtlFreeHeap( GetProcessHeap(), 0, fileio ); + else NtCurrentTeb()->num_async_io++; goto done; } else /* synchronous write, wait for the fd to become ready */