Fully support AsyncSelect by re-enabling events. Also, FD_CONNECT stuff isn't quite right, I need to investigate more.

svn path=/trunk/; revision=12372
This commit is contained in:
Alex Ionescu 2004-12-27 21:18:07 +00:00
parent dc88a45c29
commit 190c2b5fc1
3 changed files with 95 additions and 3 deletions

View file

@ -460,6 +460,12 @@ VOID SockProcessQueuedAsyncSelect(
PIO_STATUS_BLOCK IoStatusBlock
);
VOID
SockReenableAsyncSelectEvent (
IN PSOCKET_INFORMATION Socket,
IN ULONG Event
);
DWORD MsafdReturnWithErrno( NTSTATUS Status, LPINT Errno, DWORD Received,
LPDWORD ReturnedBytes );

View file

@ -975,6 +975,9 @@ WSPAccept(
NtClose( SockEvent );
/* Re-enable Async Event */
SockReenableAsyncSelectEvent(Socket, FD_ACCEPT);
AFD_DbgPrint(MID_TRACE,("Socket %x\n", AcceptSocket));
/* Return Socket */
@ -1054,6 +1057,16 @@ WSPConnect(
SocketAddress->sa_data,
SocketAddressLength - sizeof(SocketAddress->sa_family));
/*
* Disable FD_WRITE and FD_CONNECT
* The latter fixes a race condition where the FD_CONNECT is re-enabled
* at the end of this function right after the Async Thread disables it.
* This should only happen at the *next* WSPConnect
*/
if (Socket->SharedData.AsyncEvents & FD_CONNECT) {
Socket->SharedData.AsyncDisabledEvents |= FD_CONNECT | FD_WRITE;
}
/* Tell AFD that we want Connection Data back, have it allocate a buffer */
if (lpCalleeData != NULL) {
InConnectDataLength = lpCalleeData->len;
@ -1074,6 +1087,11 @@ WSPConnect(
ConnectInfo->UseSAN = FALSE;
ConnectInfo->Unknown = 0;
/* FIXME: Handle Async Connect */
if (Socket->SharedData.NonBlocking) {
AFD_DbgPrint(MIN_TRACE, ("Async Connect UNIMPLEMENTED!\n"));
}
/* Send IOCTL */
Status = NtDeviceIoControlFile((HANDLE)Handle,
SockEvent,
@ -1100,6 +1118,12 @@ WSPConnect(
lpCalleeData->len);
}
/* Re-enable Async Event */
SockReenableAsyncSelectEvent(Socket, FD_WRITE);
/* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
SockReenableAsyncSelectEvent(Socket, FD_CONNECT);
AFD_DbgPrint(MID_TRACE,("Ending\n"));
NtClose( SockEvent );
@ -1717,7 +1741,6 @@ VOID SockAsyncSelectCompletionRoutine(PVOID Context, PIO_STATUS_BLOCK IoStatusBl
return;
}
for (x = 1; x; x<<=1) {
switch (AsyncData->AsyncSelectInfo.Handles[0].Events & x) {
case AFD_EVENT_RECEIVE:
@ -1756,6 +1779,7 @@ VOID SockAsyncSelectCompletionRoutine(PVOID Context, PIO_STATUS_BLOCK IoStatusBl
}
break;
/* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
case AFD_EVENT_CONNECT:
if (0 != (Socket->SharedData.AsyncEvents & FD_CONNECT) && 0 == (Socket->SharedData.AsyncDisabledEvents & FD_CONNECT)) {
/* Make the Notifcation */
@ -1842,6 +1866,7 @@ VOID SockProcessAsyncSelect(PSOCKET_INFORMATION Socket, PASYNC_DATA AsyncData)
AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_ACCEPT;
}
/* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
if (lNetworkEvents & FD_CONNECT) {
AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_CONNECT | AFD_EVENT_CONNECT_FAIL;
}
@ -1908,6 +1933,51 @@ VOID SockProcessQueuedAsyncSelect(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
return;
}
VOID
SockReenableAsyncSelectEvent (
IN PSOCKET_INFORMATION Socket,
IN ULONG Event
)
{
PASYNC_DATA AsyncData;
/* Make sure the event is actually disabled */
if (!(Socket->SharedData.AsyncDisabledEvents & Event)) {
return;
}
/* Re-enable it */
Socket->SharedData.AsyncDisabledEvents &= ~Event;
/* Return if no more events are being polled */
if ((Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents)) == 0 ) {
return;
}
/* Wait on new events */
AsyncData = HeapAlloc(GetProcessHeap(), 0, sizeof(ASYNC_DATA));
/* Create the Asynch Thread if Needed */
SockCreateOrReferenceAsyncThread();
/* Increase the sequence number to stop anything else */
Socket->SharedData.SequenceNumber++;
/* Set up the Async Data */
AsyncData->ParentSocket = Socket;
AsyncData->SequenceNumber = Socket->SharedData.SequenceNumber;
/* Begin Async Select by using I/O Completion */
NtSetIoCompletion(SockAsyncCompletionPort,
(PVOID)&SockProcessQueuedAsyncSelect,
AsyncData,
0,
0);
/* All done */
return;
}
BOOL
STDCALL
DllMain(HANDLE hInstDll,

View file

@ -76,7 +76,7 @@ WSPAsyncSelect(
0);
/* Return */
return 0;
return ERROR_SUCCESS;
}
@ -208,6 +208,13 @@ WSPRecv(
case STATUS_RECEIVE_PARTIAL: *ReceiveFlags = MSG_PARTIAL; break;
}
/* Re-enable Async Event */
if (*ReceiveFlags == MSG_OOB) {
SockReenableAsyncSelectEvent(Socket, FD_OOB);
} else {
SockReenableAsyncSelectEvent(Socket, FD_READ);
}
return MsafdReturnWithErrno
( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead );
}
@ -337,6 +344,9 @@ WSPRecvFrom(
case STATUS_RECEIVE_PARTIAL: *ReceiveFlags = MSG_PARTIAL; break;
}
/* Re-enable Async Event */
SockReenableAsyncSelectEvent(Socket, FD_READ);
return MsafdReturnWithErrno
( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead );
}
@ -448,6 +458,9 @@ WSPSend(
return WSA_IO_PENDING;
}
/* Re-enable Async Event */
SockReenableAsyncSelectEvent(Socket, FD_WRITE);
AFD_DbgPrint(MID_TRACE,("Leaving (Success, %d)\n", IOSB->Information));
return MsafdReturnWithErrno
@ -573,6 +586,9 @@ WSPSendTo(
return WSA_IO_PENDING;
}
/* Re-enable Async Event */
SockReenableAsyncSelectEvent(Socket, FD_WRITE);
return MsafdReturnWithErrno
( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent );
}