mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
[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) svn path=/trunk/; revision=52510
This commit is contained in:
parent
82562115f8
commit
afa2c1d664
4 changed files with 32 additions and 10 deletions
|
@ -70,7 +70,18 @@ AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
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",
|
||||
|
|
|
@ -553,7 +553,8 @@ DisconnectComplete(PDEVICE_OBJECT DeviceObject,
|
|||
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 @@ DoDisconnect(PAFD_FCB FCB)
|
|||
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 @@ RetryDisconnectCompletion(PAFD_FCB FCB)
|
|||
{
|
||||
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 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,8 +31,8 @@ static VOID HandleEOFOnIrp( PAFD_FCB FCB, NTSTATUS Status, ULONG_PTR Information
|
|||
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 );
|
||||
|
|
|
@ -179,7 +179,10 @@ static NTSTATUS NTAPI SendComplete
|
|||
&FCB->SendIrp.Iosb,
|
||||
SendComplete,
|
||||
FCB );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nothing is waiting so try to complete a pending disconnect */
|
||||
RetryDisconnectCompletion(FCB);
|
||||
}
|
||||
|
||||
|
@ -300,6 +303,12 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
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 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
FCB->PollState &= ~AFD_EVENT_SEND;
|
||||
}
|
||||
|
||||
RetryDisconnectCompletion(FCB);
|
||||
|
||||
return UnlockAndMaybeComplete
|
||||
( FCB, Status, Irp, TotalBytesCopied );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue