Author: cgutman Date: Fri Jul 22 04:11:50 2011 New Revision: 52774
URL: http://svn.reactos.org/svn/reactos?rev=52774&view=rev Log: [AFD] - Wait to signal a graceful receive shutdown until all buffered transport data is read by the application
Modified: trunk/reactos/drivers/network/afd/afd/read.c trunk/reactos/drivers/network/afd/include/afd.h
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] Fri Jul 22 04:11:50 2011 @@ -28,27 +28,32 @@
static VOID HandleEOFOnIrp( PAFD_FCB FCB, NTSTATUS Status, ULONG_PTR Information ) { - if( ( Status == STATUS_SUCCESS && !Information ) || - ( !NT_SUCCESS( Status ) ) ) + if (Status != STATUS_SUCCESS) { - /* The socket has been closed by the remote side */ + FCB->TdiReceiveClosed = TRUE; + + /* Signal unexpected termination immediately */ FCB->PollState |= AFD_EVENT_ABORT; FCB->PollStatus[FD_CLOSE_BIT] = Status; - + PollReeval( FCB->DeviceExt, FCB->FileObject ); } + else if (Status == STATUS_SUCCESS && !Information) + { + /* Wait to signal graceful close until all data is read */ + FCB->TdiReceiveClosed = TRUE; + } }
static BOOLEAN CantReadMore( PAFD_FCB FCB ) { UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed; - return !BytesAvailable && - (FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_ABORT)); + return !BytesAvailable && FCB->TdiReceiveClosed; }
static VOID RefillSocketBuffer( PAFD_FCB FCB ) { if( !FCB->ReceiveIrp.InFlightRequest && - !(FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_ABORT)) ) { + !FCB->TdiReceiveClosed ) { AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n"));
TdiReceive( &FCB->ReceiveIrp.InFlightRequest, @@ -225,8 +230,21 @@ FCB->PollState |= AFD_EVENT_RECEIVE; FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS; PollReeval( FCB->DeviceExt, FCB->FileObject ); - } else + } + else if (CantReadMore(FCB) && !(FCB->PollState & (AFD_EVENT_ABORT | AFD_EVENT_CLOSE))) + { FCB->PollState &= ~AFD_EVENT_RECEIVE; + + /* Signal delayed close event */ + FCB->PollState |= AFD_EVENT_ABORT; + FCB->PollStatus[FD_CLOSE_BIT] = STATUS_SUCCESS; + + PollReeval( FCB->DeviceExt, FCB->FileObject ); + } + else + { + FCB->PollState &= ~AFD_EVENT_RECEIVE; + }
AFD_DbgPrint(MID_TRACE,("RetStatus for irp %x is %x\n", Irp, RetStatus));
Modified: trunk/reactos/drivers/network/afd/include/afd.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/include... ============================================================================== --- trunk/reactos/drivers/network/afd/include/afd.h [iso-8859-1] (original) +++ trunk/reactos/drivers/network/afd/include/afd.h [iso-8859-1] Fri Jul 22 04:11:50 2011 @@ -173,7 +173,7 @@ } AFD_STORED_DATAGRAM, *PAFD_STORED_DATAGRAM;
typedef struct _AFD_FCB { - BOOLEAN Locked, Critical, Overread, NonBlocking, OobInline; + BOOLEAN Locked, Critical, Overread, NonBlocking, OobInline, TdiReceiveClosed; UINT State, Flags, GroupID, GroupType; KIRQL OldIrql; UINT LockCount;