Author: cgutman Date: Sun Jul 3 01:53:10 2011 New Revision: 52510
URL: http://svn.reactos.org/svn/reactos?rev=52510&view=rev Log: [AFD] - We really do need to count the outstanding send IRP in our pending send count (with a detailed explanation of the reason included in the code) - Wait on an outstanding send IRP to dispatch the disconnect - When we receive a FIN from the other side and our receive comes back with 0 data, only close receiving on the socket because sending is still legal in this state - Fixes many bugs on the ws2_32_winetest sock and likely lots of other partial disconnect related stuff - Retest network related hanging bugs after this please (ftp dir hang is fixed)
Modified: trunk/reactos/drivers/network/afd/afd/info.c trunk/reactos/drivers/network/afd/afd/main.c trunk/reactos/drivers/network/afd/afd/read.c trunk/reactos/drivers/network/afd/afd/write.c
Modified: trunk/reactos/drivers/network/afd/afd/info.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/inf... ============================================================================== --- trunk/reactos/drivers/network/afd/afd/info.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/afd/afd/info.c [iso-8859-1] Sun Jul 3 01:53:10 2011 @@ -70,7 +70,18 @@ CurrentEntry = CurrentEntry->Flink; }
- break; + /* This needs to count too because when this is dispatched + * the user-mode IRP has already been completed and therefore + * will NOT be in our pending IRP list. We count this as one send + * outstanding although it could be multiple since we batch sends + * when waiting for the in flight request to return, so this number + * may not be accurate but it really doesn't matter that much since + * it's more or less a zero/non-zero comparison to determine whether + * we can shutdown the socket + */ + if (FCB->SendIrp.InFlightRequest) + InfoReq->Information.Ulong++; + break;
default: AFD_DbgPrint(MID_TRACE,("Unknown info id %x\n",
Modified: trunk/reactos/drivers/network/afd/afd/main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/mai... ============================================================================== --- trunk/reactos/drivers/network/afd/afd/main.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/afd/afd/main.c [iso-8859-1] Sun Jul 3 01:53:10 2011 @@ -553,7 +553,8 @@ FCB->DisconnectIrp.InFlightRequest = NULL;
ASSERT(FCB->DisconnectPending); - //ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) || (FCB->DisconnectFlags & TDI_DISCONNECT_ABORT)); + ASSERT((IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && !FCB->SendIrp.InFlightRequest) || + (FCB->DisconnectFlags & TDI_DISCONNECT_ABORT));
if (NT_SUCCESS(Irp->IoStatus.Status) && (FCB->DisconnectFlags & TDI_DISCONNECT_RELEASE)) { @@ -606,6 +607,8 @@ NTSTATUS Status;
ASSERT(FCB->DisconnectPending); + ASSERT((IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && !FCB->SendIrp.InFlightRequest) || + (FCB->DisconnectFlags & TDI_DISCONNECT_ABORT));
if (FCB->DisconnectIrp.InFlightRequest) { @@ -639,7 +642,7 @@ { ASSERT(FCB->RemoteAddress);
- if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && FCB->DisconnectPending) + if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && !FCB->SendIrp.InFlightRequest && FCB->DisconnectPending) { /* Sends are done; fire off a TDI_DISCONNECT request */ DoDisconnect(FCB); @@ -704,9 +707,10 @@ Status = QueueUserModeIrp(FCB, Irp, FUNCTION_DISCONNECT); if (Status == STATUS_PENDING) { - if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) || (FCB->DisconnectFlags & TDI_DISCONNECT_ABORT)) + if ((IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && !FCB->SendIrp.InFlightRequest) || + (FCB->DisconnectFlags & TDI_DISCONNECT_ABORT)) { - /* Go ahead an execute the disconnect because we're ready for it */ + /* Go ahead and execute the disconnect because we're ready for it */ Status = DoDisconnect(FCB); }
Modified: trunk/reactos/drivers/network/afd/afd/read.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/rea... ============================================================================== --- trunk/reactos/drivers/network/afd/afd/read.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/afd/afd/read.c [iso-8859-1] Sun Jul 3 01:53:10 2011 @@ -31,8 +31,8 @@ if( ( Status == STATUS_SUCCESS && !Information ) || ( !NT_SUCCESS( Status ) ) ) { - /* The socket has been closed */ - FCB->PollState |= AFD_EVENT_CLOSE; + /* The socket has been closed by the remote side */ + FCB->PollState |= AFD_EVENT_ABORT; FCB->PollStatus[FD_CLOSE_BIT] = Status; PollReeval( FCB->DeviceExt, FCB->FileObject );
Modified: trunk/reactos/drivers/network/afd/afd/write.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/wri... ============================================================================== --- trunk/reactos/drivers/network/afd/afd/write.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/afd/afd/write.c [iso-8859-1] Sun Jul 3 01:53:10 2011 @@ -179,7 +179,10 @@ &FCB->SendIrp.Iosb, SendComplete, FCB ); - + } + else + { + /* Nothing is waiting so try to complete a pending disconnect */ RetryDisconnectCompletion(FCB); }
@@ -300,6 +303,12 @@ return UnlockAndMaybeComplete( FCB, Status, Irp, Information ); }
+ if (FCB->DisconnectPending && (FCB->DisconnectFlags & TDI_DISCONNECT_RELEASE)) + { + /* We're pending a send shutdown so don't accept anymore sends */ + return UnlockAndMaybeComplete(FCB, STATUS_FILE_CLOSED, Irp, 0); + } + if (FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_DISCONNECT)) { if (FCB->PollStatus[FD_CLOSE_BIT] == STATUS_SUCCESS) @@ -435,8 +444,6 @@ FCB->PollState &= ~AFD_EVENT_SEND; }
- RetryDisconnectCompletion(FCB); - return UnlockAndMaybeComplete ( FCB, Status, Irp, TotalBytesCopied ); }