server: Always return STATUS_PENDING when an async I/O operation has been queued.
This commit is contained in:
parent
cc578af7b1
commit
589ce2bb8d
@ -282,14 +282,13 @@ static ULONG fileio_queue_async(async_fileio* fileio, IO_STATUS_BLOCK* iosb,
|
|||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
if ( status ) iosb->u.Status = status;
|
if (status != STATUS_PENDING)
|
||||||
if ( iosb->u.Status != STATUS_PENDING )
|
|
||||||
{
|
{
|
||||||
|
iosb->u.Status = status;
|
||||||
(apc)( fileio, iosb, iosb->u.Status );
|
(apc)( fileio, iosb, iosb->u.Status );
|
||||||
return iosb->u.Status;
|
|
||||||
}
|
}
|
||||||
NtCurrentTeb()->num_async_io++;
|
else NtCurrentTeb()->num_async_io++;
|
||||||
return STATUS_SUCCESS;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@ -531,7 +530,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
|
|||||||
|
|
||||||
io_status->u.Status = STATUS_PENDING;
|
io_status->u.Status = STATUS_PENDING;
|
||||||
ret = fileio_queue_async(fileio, io_status, TRUE);
|
ret = fileio_queue_async(fileio, io_status, TRUE);
|
||||||
if (ret != STATUS_SUCCESS)
|
if (ret != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
if (flags & FD_FLAG_TIMEOUT) NtClose(hEvent);
|
if (flags & FD_FLAG_TIMEOUT) NtClose(hEvent);
|
||||||
return ret;
|
return ret;
|
||||||
@ -762,7 +761,7 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
|
|||||||
io_status->Information = 0;
|
io_status->Information = 0;
|
||||||
io_status->u.Status = STATUS_PENDING;
|
io_status->u.Status = STATUS_PENDING;
|
||||||
ret = fileio_queue_async(fileio, io_status, FALSE);
|
ret = fileio_queue_async(fileio, io_status, FALSE);
|
||||||
if (ret != STATUS_SUCCESS)
|
if (ret != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
if (flags & FD_FLAG_TIMEOUT) NtClose(hEvent);
|
if (flags & FD_FLAG_TIMEOUT) NtClose(hEvent);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1150,6 +1150,7 @@ static ULONG ws2_queue_async(struct ws2_async* wsa, IO_STATUS_BLOCK* iosb)
|
|||||||
default: FIXME("Unknown internal mode (%d)\n", wsa->mode); return STATUS_INVALID_PARAMETER;
|
default: FIXME("Unknown internal mode (%d)\n", wsa->mode); return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iosb->u.Status = STATUS_PENDING;
|
||||||
SERVER_START_REQ( register_async )
|
SERVER_START_REQ( register_async )
|
||||||
{
|
{
|
||||||
req->handle = wsa->hSocket;
|
req->handle = wsa->hSocket;
|
||||||
@ -1163,18 +1164,13 @@ static ULONG ws2_queue_async(struct ws2_async* wsa, IO_STATUS_BLOCK* iosb)
|
|||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
if ( status ) iosb->u.Status = status;
|
if (status != STATUS_PENDING)
|
||||||
if ( iosb->u.Status != STATUS_PENDING )
|
|
||||||
{
|
{
|
||||||
/* Note: we get here a non zero status when we couldn't queue the async
|
iosb->u.Status = status;
|
||||||
* in the server. Therefore, we simply terminate the async.
|
|
||||||
*/
|
|
||||||
status = iosb->u.Status;
|
|
||||||
ws2_async_terminate(wsa, iosb);
|
ws2_async_terminate(wsa, iosb);
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
NtCurrentTeb()->num_async_io++;
|
else NtCurrentTeb()->num_async_io++;
|
||||||
return STATUS_SUCCESS;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@ -1500,7 +1496,7 @@ static int WS2_register_async_shutdown( SOCKET s, enum ws2_mode mode )
|
|||||||
|
|
||||||
/* Hack: this will cause ws2_async_terminate() to free the overlapped structure */
|
/* Hack: this will cause ws2_async_terminate() to free the overlapped structure */
|
||||||
wsa->user_overlapped = NULL;
|
wsa->user_overlapped = NULL;
|
||||||
if ( (ret = ws2_queue_async( wsa, iosb )) )
|
if ((ret = ws2_queue_async( wsa, iosb )) != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
err = NtStatusToWSAError( ret );
|
err = NtStatusToWSAError( ret );
|
||||||
goto out;
|
goto out;
|
||||||
@ -2843,7 +2839,7 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
|
|||||||
goto err_free;
|
goto err_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ( ret = ws2_queue_async( wsa, iosb ) ) )
|
if ((ret = ws2_queue_async( wsa, iosb )) != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
err = NtStatusToWSAError( ret );
|
err = NtStatusToWSAError( ret );
|
||||||
|
|
||||||
@ -4349,7 +4345,7 @@ INT WINAPI WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
|
|||||||
goto err_free;
|
goto err_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ( ret = ws2_queue_async( wsa, iosb )) )
|
if ((ret = ws2_queue_async( wsa, iosb )) != STATUS_PENDING)
|
||||||
{
|
{
|
||||||
err = NtStatusToWSAError( ret );
|
err = NtStatusToWSAError( ret );
|
||||||
|
|
||||||
|
@ -1742,6 +1742,7 @@ void fd_queue_async_timeout( struct fd *fd, const async_data_t *data, int type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!create_async( current, timeout, queue, data )) return;
|
if (!create_async( current, timeout, queue, data )) return;
|
||||||
|
set_error( STATUS_PENDING );
|
||||||
|
|
||||||
/* Check if the new pending request can be served immediately */
|
/* Check if the new pending request can be served immediately */
|
||||||
events = check_fd_events( fd, fd->fd_ops->get_poll_events( fd ) );
|
events = check_fd_events( fd, fd->fd_ops->get_poll_events( fd ) );
|
||||||
@ -1938,8 +1939,6 @@ DECL_HANDLER(register_async)
|
|||||||
* Usually: set_elect_events (obj, obj->ops->get_poll_events()).
|
* Usually: set_elect_events (obj, obj->ops->get_poll_events()).
|
||||||
* 4. When the async request is triggered, then send back (with a proper APC)
|
* 4. When the async request is triggered, then send back (with a proper APC)
|
||||||
* the trigger (STATUS_ALERTED) to the thread that posted the request.
|
* the trigger (STATUS_ALERTED) to the thread that posted the request.
|
||||||
* async_destroy() is to be called: it will both notify the sender about
|
|
||||||
* the trigger and destroy the request by itself
|
|
||||||
* See also the implementations in file.c, serial.c, and sock.c.
|
* See also the implementations in file.c, serial.c, and sock.c.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -273,6 +273,7 @@ static void serial_queue_async( struct fd *fd, const async_data_t *data, int typ
|
|||||||
|
|
||||||
add_timeout( &when, timeout );
|
add_timeout( &when, timeout );
|
||||||
if (!create_async( current, timeout ? &when : NULL, queue, data )) return;
|
if (!create_async( current, timeout ? &when : NULL, queue, data )) return;
|
||||||
|
set_error( STATUS_PENDING );
|
||||||
|
|
||||||
/* Check if the new pending request can be served immediately */
|
/* Check if the new pending request can be served immediately */
|
||||||
events = check_fd_events( fd, serial_get_poll_events( fd ) );
|
events = check_fd_events( fd, serial_get_poll_events( fd ) );
|
||||||
|
@ -545,6 +545,7 @@ static void sock_queue_async( struct fd *fd, const async_data_t *data, int type,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!create_async( current, NULL, queue, data )) return;
|
if (!create_async( current, NULL, queue, data )) return;
|
||||||
|
set_error( STATUS_PENDING );
|
||||||
}
|
}
|
||||||
|
|
||||||
pollev = sock_reselect( sock );
|
pollev = sock_reselect( sock );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user