[ros-diffs] [cgutman] 52415: [AFD] - Hold on to the disconnect IRP until all pending sending IRPs are sent to the transport driver if a controlled disconnect was requested

cgutman at svn.reactos.org cgutman at svn.reactos.org
Wed Jun 22 00:17:19 UTC 2011


Author: cgutman
Date: Wed Jun 22 00:17:19 2011
New Revision: 52415

URL: http://svn.reactos.org/svn/reactos?rev=52415&view=rev
Log:
[AFD]
- Hold on to the disconnect IRP until all pending sending IRPs are sent to the transport driver if a controlled disconnect was requested

Modified:
    trunk/reactos/drivers/network/afd/afd/main.c
    trunk/reactos/drivers/network/afd/afd/write.c
    trunk/reactos/drivers/network/afd/include/afd.h

Modified: trunk/reactos/drivers/network/afd/afd/main.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/main.c?rev=52415&r1=52414&r2=52415&view=diff
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/main.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/main.c [iso-8859-1] Wed Jun 22 00:17:19 2011
@@ -440,6 +440,7 @@
     ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]));
     ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_RECV]));
     ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_PREACCEPT]));
+    ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT]))
 
     while (!IsListEmpty(&FCB->PendingConnections))
     {
@@ -531,58 +532,44 @@
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS NTAPI
-AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
-	      PIO_STACK_LOCATION IrpSp) {
-    PFILE_OBJECT FileObject = IrpSp->FileObject;
-    PAFD_FCB FCB = FileObject->FsContext;
+static
+NTSTATUS
+DoDisconnect(PAFD_FCB FCB, PIRP CurrentIrp)
+{
     PAFD_DISCONNECT_INFO DisReq;
     IO_STATUS_BLOCK Iosb;
     PTDI_CONNECTION_INFORMATION ConnectionReturnInfo;
-    NTSTATUS Status = STATUS_SUCCESS;
+    PIO_STACK_LOCATION CurrentIrpSp;
     USHORT Flags = 0;
-
-    if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
-
-    if( !(DisReq = LockRequest( Irp, IrpSp )) )
-	return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
-				       Irp, 0 );
+    NTSTATUS Status;
+    
+    CurrentIrpSp = IoGetCurrentIrpStackLocation(CurrentIrp);
+    DisReq = GetLockedData(CurrentIrp, CurrentIrpSp);
     
     if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
 	    Flags |= TDI_DISCONNECT_RELEASE;
     if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
        DisReq->DisconnectType & AFD_DISCONNECT_ABORT )
 	    Flags |= TDI_DISCONNECT_ABORT;
-
-    if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
-    {
-        if( !FCB->ConnectInfo )
-            return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER,
-                                           Irp, 0 );
-
-        ASSERT(FCB->RemoteAddress);
-
-        Status = TdiBuildNullConnectionInfo
-	       ( &ConnectionReturnInfo, FCB->RemoteAddress->Address[0].AddressType );
-
-        if( !NT_SUCCESS(Status) )
-	    return UnlockAndMaybeComplete( FCB, Status,
-				           Irp, 0 );
-
+    
+    Status = TdiBuildNullConnectionInfo(&ConnectionReturnInfo,
+                                        FCB->RemoteAddress->Address[0].AddressType);
+    if (NT_SUCCESS(Status))
+    {
         FCB->ConnectInfo->UserData = FCB->DisconnectData;
         FCB->ConnectInfo->UserDataLength = FCB->DisconnectDataSize;
         FCB->ConnectInfo->Options = FCB->DisconnectOptions;
         FCB->ConnectInfo->OptionsLength = FCB->DisconnectOptionsSize;
-
-        Status = TdiDisconnect( FCB->Connection.Object,
-			        &DisReq->Timeout,
-			        Flags,
-			        &Iosb,
-			        NULL,
-			        NULL,
-			        FCB->ConnectInfo,
-			        ConnectionReturnInfo);
-
+        
+        Status = TdiDisconnect(FCB->Connection.Object,
+                               &DisReq->Timeout,
+                               Flags,
+                               &Iosb,
+                               NULL,
+                               NULL,
+                               FCB->ConnectInfo,
+                               ConnectionReturnInfo);
+        
         if (NT_SUCCESS(Status)) {
             FCB->FilledDisconnectData = MIN(FCB->DisconnectDataSize, ConnectionReturnInfo->UserDataLength);
             if (FCB->FilledDisconnectData)
@@ -591,7 +578,7 @@
                               ConnectionReturnInfo->UserData,
                               FCB->FilledDisconnectData);
             }
-
+            
             FCB->FilledDisconnectOptions = MIN(FCB->DisconnectOptionsSize, ConnectionReturnInfo->OptionsLength);
             if (FCB->FilledDisconnectOptions)
             {
@@ -600,15 +587,90 @@
                               FCB->FilledDisconnectOptions);
             }
         }
-
+        
         ExFreePool( ConnectionReturnInfo );
-
+        
         if (Flags & TDI_DISCONNECT_RELEASE)
             FCB->PollState |= AFD_EVENT_DISCONNECT;
         else
             FCB->PollState |= AFD_EVENT_ABORT;
-        FCB->PollStatus[FD_CLOSE_BIT] = STATUS_SUCCESS;
+        FCB->PollStatus[FD_CLOSE_BIT] = Status;
         PollReeval( FCB->DeviceExt, FCB->FileObject );
+    }
+    
+    CurrentIrp->IoStatus.Status = Status;
+    CurrentIrp->IoStatus.Information = 0;
+    UnlockRequest(CurrentIrp, CurrentIrpSp);
+    (void)IoSetCancelRoutine(CurrentIrp, NULL);
+    
+    IoCompleteRequest(CurrentIrp, IO_NETWORK_INCREMENT);
+    
+    return Status;
+}
+
+VOID
+RetryDisconnectCompletion(PAFD_FCB FCB)
+{
+    if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]))
+    {
+        PIRP CurrentIrp;
+        PLIST_ENTRY CurrentEntry;
+        
+        ASSERT(FCB->RemoteAddress);
+        
+        while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT]))
+        {
+            CurrentEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_DISCONNECT]);
+            CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry);
+            
+            DoDisconnect(FCB, CurrentIrp);
+        }
+    }
+}
+
+static NTSTATUS NTAPI
+AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+	      PIO_STACK_LOCATION IrpSp) {
+    PFILE_OBJECT FileObject = IrpSp->FileObject;
+    PAFD_FCB FCB = FileObject->FsContext;
+    PAFD_DISCONNECT_INFO DisReq;
+    NTSTATUS Status = STATUS_SUCCESS;
+    USHORT Flags = 0;
+
+    if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
+
+    if( !(DisReq = LockRequest( Irp, IrpSp )) )
+	return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
+				       Irp, 0 );
+    
+    if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
+	    Flags |= TDI_DISCONNECT_RELEASE;
+    if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
+       DisReq->DisconnectType & AFD_DISCONNECT_ABORT )
+	    Flags |= TDI_DISCONNECT_ABORT;
+
+    if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
+    {
+        if( !FCB->ConnectInfo )
+            return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER,
+                                           Irp, 0 );
+        
+        if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) || (Flags & TDI_DISCONNECT_ABORT))
+        {
+            /* Go ahead an execute the disconnect because we're ready for it */
+            Status = DoDisconnect(FCB, Irp);
+            
+            /* DoDisconnect takes care of the IRP */
+            SocketStateUnlock(FCB);
+            
+            return Status;
+        }
+        else
+        {
+            /* We have a graceful disconnect waiting on pending sends to complete */
+            return LeaveIrpUntilLater(FCB, Irp, FUNCTION_DISCONNECT);
+        }
+
     }
     else
     {
@@ -924,6 +986,10 @@
         DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (IOCTL_AFD_SELECT)\n");
         return;
             
+        case IOCTL_AFD_DISCONNECT:
+        Function = FUNCTION_DISCONNECT;
+        break;
+            
         default:
         ASSERT(FALSE);
         UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0);

Modified: trunk/reactos/drivers/network/afd/afd/write.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/write.c?rev=52415&r1=52414&r2=52415&view=diff
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/write.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/write.c [iso-8859-1] Wed Jun 22 00:17:19 2011
@@ -59,8 +59,11 @@
                (void)IoSetCancelRoutine(NextIrp, NULL);
 	       IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
         }
-	SocketStateUnlock( FCB );
-	return STATUS_FILE_CLOSED;
+        
+        RetryDisconnectCompletion(FCB);
+        
+        SocketStateUnlock( FCB );
+        return STATUS_FILE_CLOSED;
     }
 
     if( !NT_SUCCESS(Status) ) {
@@ -85,6 +88,8 @@
                         (void)IoSetCancelRoutine(NextIrp, NULL);
 			IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
 		}
+        
+        RetryDisconnectCompletion(FCB);
 
 		SocketStateUnlock( FCB );
 
@@ -164,6 +169,8 @@
 						  &FCB->SendIrp.Iosb,
 						  SendComplete,
 						  FCB );
+        
+        RetryDisconnectCompletion(FCB);
     } else {
 		FCB->PollState |= AFD_EVENT_SEND;
 		FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
@@ -410,6 +417,8 @@
                                 Status, TotalBytesCopied));
     }
     
+    RetryDisconnectCompletion(FCB);
+    
     return UnlockAndMaybeComplete
     ( FCB, Status, Irp, TotalBytesCopied );
 }

Modified: trunk/reactos/drivers/network/afd/include/afd.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/include/afd.h?rev=52415&r1=52414&r2=52415&view=diff
==============================================================================
--- trunk/reactos/drivers/network/afd/include/afd.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/include/afd.h [iso-8859-1] Wed Jun 22 00:17:19 2011
@@ -99,8 +99,9 @@
 #define FUNCTION_SEND                   2
 #define FUNCTION_PREACCEPT              3
 #define FUNCTION_ACCEPT                 4
-#define FUNCTION_CLOSE                  5
-#define MAX_FUNCTIONS                   6
+#define FUNCTION_DISCONNECT             5
+#define FUNCTION_CLOSE                  6
+#define MAX_FUNCTIONS                   7
 
 #define IN_FLIGHT_REQUESTS              4
 
@@ -309,6 +310,7 @@
 VOID DestroySocket( PAFD_FCB FCB );
 VOID NTAPI AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
                  PIRP Irp);
+VOID RetryDisconnectCompletion(PAFD_FCB FCB);
 
 /* read.c */
 




More information about the Ros-diffs mailing list