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/in…
==============================================================================
--- 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/ma…
==============================================================================
--- 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/re…
==============================================================================
--- 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/wr…
==============================================================================
--- 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 );
}