ntdll: Simplify the async read/write code now that most of the work is done in the server.
This commit is contained in:
parent
72bff2e445
commit
6dcb280bc5
|
@ -236,57 +236,24 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* Asynchronous file I/O *
|
* 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;
|
HANDLE handle;
|
||||||
PIO_APC_ROUTINE apc;
|
|
||||||
void* apc_user;
|
|
||||||
char* buffer;
|
char* buffer;
|
||||||
unsigned int already;
|
unsigned int already;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
BOOL avail_mode;
|
BOOL avail_mode;
|
||||||
HANDLE event;
|
} async_fileio_read;
|
||||||
} async_fileio;
|
|
||||||
|
|
||||||
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)
|
* FILE_GetNtStatus(void)
|
||||||
|
@ -339,7 +306,7 @@ NTSTATUS FILE_GetNtStatus(void)
|
||||||
*/
|
*/
|
||||||
static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status)
|
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;
|
int fd, needs_close, result;
|
||||||
|
|
||||||
TRACE("%p %p 0x%x\n", iosb, fileio->buffer, status);
|
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;
|
if (fileio->already) status = STATUS_SUCCESS;
|
||||||
break;
|
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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,7 +552,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
|
||||||
|
|
||||||
if (flags & FD_FLAG_OVERLAPPED)
|
if (flags & FD_FLAG_OVERLAPPED)
|
||||||
{
|
{
|
||||||
async_fileio *fileio;
|
async_fileio_read *fileio;
|
||||||
|
|
||||||
if (total && (flags & FD_FLAG_AVAILABLE))
|
if (total && (flags & FD_FLAG_AVAILABLE))
|
||||||
{
|
{
|
||||||
|
@ -588,7 +560,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(fileio = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(async_fileio))))
|
if (!(fileio = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(*fileio))))
|
||||||
{
|
{
|
||||||
status = STATUS_NO_MEMORY;
|
status = STATUS_NO_MEMORY;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -596,12 +568,26 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
|
||||||
fileio->handle = hFile;
|
fileio->handle = hFile;
|
||||||
fileio->already = total;
|
fileio->already = total;
|
||||||
fileio->count = length;
|
fileio->count = length;
|
||||||
fileio->apc = apc;
|
|
||||||
fileio->apc_user = apc_user;
|
|
||||||
fileio->buffer = buffer;
|
fileio->buffer = buffer;
|
||||||
fileio->avail_mode = (flags & FD_FLAG_AVAILABLE);
|
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;
|
goto done;
|
||||||
}
|
}
|
||||||
else /* synchronous read, wait for the fd to become ready */
|
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)
|
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;
|
int result, fd, needs_close;
|
||||||
enum server_fd_type type;
|
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;
|
if (fileio->already) status = STATUS_SUCCESS;
|
||||||
break;
|
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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -799,9 +790,9 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
|
||||||
|
|
||||||
if (flags & FD_FLAG_OVERLAPPED)
|
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;
|
status = STATUS_NO_MEMORY;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -809,11 +800,25 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
|
||||||
fileio->handle = hFile;
|
fileio->handle = hFile;
|
||||||
fileio->already = total;
|
fileio->already = total;
|
||||||
fileio->count = length;
|
fileio->count = length;
|
||||||
fileio->apc = apc;
|
fileio->buffer = buffer;
|
||||||
fileio->apc_user = apc_user;
|
|
||||||
fileio->buffer = (void*)buffer;
|
SERVER_START_REQ( register_async )
|
||||||
fileio->event = hEvent;
|
{
|
||||||
status = fileio_queue_async(fileio, io_status, FALSE);
|
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;
|
goto done;
|
||||||
}
|
}
|
||||||
else /* synchronous write, wait for the fd to become ready */
|
else /* synchronous write, wait for the fd to become ready */
|
||||||
|
|
Loading…
Reference in New Issue