Alexandre Julliard : ntdll: Simplify the async read/
write code now that most of the work is done in the server.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Apr 10 14:58:05 CDT 2007
Module: wine
Branch: master
Commit: 6dcb280bc5a36b7ddac69b4cdbb84dd2b4e041d1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6dcb280bc5a36b7ddac69b4cdbb84dd2b4e041d1
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Apr 10 17:19:24 2007 +0200
ntdll: Simplify the async read/write code now that most of the work is done in the server.
---
dlls/ntdll/file.c | 121 +++++++++++++++++++++++++++-------------------------
1 files changed, 63 insertions(+), 58 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index f3ba690..078e4fe 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);
-
- 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;
+ HANDLE handle;
+ const char *buffer;
+ unsigned int already;
+ unsigned int count;
+} async_fileio_write;
- 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 */
More information about the wine-cvs
mailing list