Uniform handling of stream socket reads. Modified: trunk/reactos/drivers/net/afd/afd/main.c Modified: trunk/reactos/drivers/net/afd/afd/read.c Modified: trunk/reactos/drivers/net/afd/include/afd.h _____
Modified: trunk/reactos/drivers/net/afd/afd/main.c --- trunk/reactos/drivers/net/afd/afd/main.c 2005-03-11 02:38:55 UTC (rev 13921) +++ trunk/reactos/drivers/net/afd/afd/main.c 2005-03-11 07:30:17 UTC (rev 13922) @@ -20,8 +20,8 @@
#ifdef DBG
/* See debug.h for debug/trace constants */ -//DWORD DebugTraceLevel = DEBUG_ULTRA; -DWORD DebugTraceLevel = 0; +DWORD DebugTraceLevel = DEBUG_ULTRA; +//DWORD DebugTraceLevel = 0;
#endif /* DBG */
_____
Modified: trunk/reactos/drivers/net/afd/afd/read.c --- trunk/reactos/drivers/net/afd/afd/read.c 2005-03-11 02:38:55 UTC (rev 13921) +++ trunk/reactos/drivers/net/afd/afd/read.c 2005-03-11 07:30:17 UTC (rev 13922) @@ -26,8 +26,6 @@
#include "tdiconn.h" #include "debug.h"
-static VOID ProcessClose( PAFD_FCB FCB ); - BOOLEAN CantReadMore( PAFD_FCB FCB ) { UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed;
@@ -106,7 +104,8 @@ if( Status == STATUS_SUCCESS ) { if( !FCB->ReceiveIrp.Iosb.Information ) { AFD_DbgPrint(MID_TRACE,("Looks like an EOF\n")); - ProcessClose( FCB ); + FCB->PollState |= AFD_EVENT_DISCONNECT; + PollReeval( FCB->DeviceExt, FCB->FileObject ); } FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information; } @@ -118,66 +117,40 @@ return STATUS_SUCCESS; }
-static VOID ProcessClose( PAFD_FCB FCB ) { +NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) { PLIST_ENTRY NextIrpEntry; PIRP NextIrp; - - AFD_DbgPrint(MID_TRACE,("Socket shutdown from remote side\n")); - - /* Kill remaining recv irps */ - while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) { - NextIrpEntry = - RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]); - NextIrp = - CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); - AFD_DbgPrint(MID_TRACE,("Completing recv %x (%x)\n", - NextIrp, STATUS_END_OF_FILE)); - NextIrp->IoStatus.Status = STATUS_SUCCESS; - NextIrp->IoStatus.Information = 0; - IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); - } - - /* Handle closing signal */ - FCB->PollState |= AFD_EVENT_DISCONNECT | SOCKET_STATE_EOF_READ; - - PollReeval( FCB->DeviceExt, FCB->FileObject ); -} - -NTSTATUS DDKAPI ReceiveComplete -( PDEVICE_OBJECT DeviceObject, - PIRP Irp, - PVOID Context ) { - NTSTATUS Status = Irp->IoStatus.Status; - PAFD_FCB FCB = (PAFD_FCB)Context; - PLIST_ENTRY NextIrpEntry; - PIRP NextIrp; PIO_STACK_LOCATION NextIrpSp; PAFD_RECV_INFO RecvReq; UINT TotalBytesCopied = 0; + NTSTATUS Status = STATUS_SUCCESS, RetStatus = STATUS_PENDING;
- AFD_DbgPrint(MID_TRACE,("Called\n")); + AFD_DbgPrint(MID_TRACE,("%x %x\n", FCB, Irp));
- ASSERT_IRQL(APC_LEVEL); - - if( !SocketAcquireStateLock( FCB ) ) return Status; - - FCB->ReceiveIrp.InFlightRequest = NULL; - FCB->Recv.Content = Irp->IoStatus.Information; - FCB->Recv.BytesUsed = 0; - - if( FCB->State == SOCKET_STATE_CLOSED ) { - AFD_DbgPrint(MIN_TRACE,("!!! CLOSED SOCK GOT A RECEIVE COMPLETE !!!\n")); - SocketStateUnlock( FCB ); - DestroySocket( FCB ); - return STATUS_SUCCESS; - } else if( FCB->State == SOCKET_STATE_LISTENING ) { - AFD_DbgPrint(MIN_TRACE,("!!! LISTENER GOT A RECEIVE COMPLETE !!!\n")); - SocketStateUnlock( FCB ); - return STATUS_UNSUCCESSFUL; - } - - if( NT_SUCCESS(Irp->IoStatus.Status) && - Irp->IoStatus.Information ) { + if( CantReadMore( FCB ) ) { + /* Success here means that we got an EOF. Complete a pending read + * with zero bytes if we haven't yet overread, then kill the others. + */ + while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) { + NextIrpEntry = + RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]); + NextIrp = + CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); + NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); + RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + + AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp, + TotalBytesCopied)); + UnlockBuffers( RecvReq->BufferArray, + RecvReq->BufferCount, FALSE ); + Status = NextIrp->IoStatus.Status = + FCB->Overread ? STATUS_END_OF_FILE : STATUS_SUCCESS; + NextIrp->IoStatus.Information = 0; + if( NextIrp == Irp ) RetStatus = Status; + IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); + FCB->Overread = TRUE; + } + } else { /* Kick the user that receive would be possible now */ /* XXX Not implemented yet */
@@ -214,31 +187,10 @@ RecvReq->BufferCount, FALSE ); NextIrp->IoStatus.Status = Status; NextIrp->IoStatus.Information = TotalBytesCopied; + if( NextIrp == Irp ) RetStatus = Status; IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } } - - Status = STATUS_SUCCESS; - } else { - /* Success here means that we got an EOF. Close all pending reads - * with EOF. Data won't have been available before. */ - while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) { - NextIrpEntry = - RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]); - NextIrp = - CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); - NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); - RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; - - AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp, - TotalBytesCopied)); - UnlockBuffers( RecvReq->BufferArray, - RecvReq->BufferCount, FALSE ); - NextIrp->IoStatus.Status = Status; - NextIrp->IoStatus.Information = 0; - IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); - } - ProcessClose( FCB ); }
if( FCB->Recv.Content ) { @@ -248,10 +200,53 @@
PollReeval( FCB->DeviceExt, FCB->FileObject );
- SocketStateUnlock( FCB ); + AFD_DbgPrint(MID_TRACE,("RetStatus for irp %x is %x\n", Irp, RetStatus));
- if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS; + return RetStatus; +}
+NTSTATUS DDKAPI ReceiveComplete +( PDEVICE_OBJECT DeviceObject, + PIRP Irp, + PVOID Context ) { + NTSTATUS Status = Irp->IoStatus.Status; + PAFD_FCB FCB = (PAFD_FCB)Context; + + AFD_DbgPrint(MID_TRACE,("Called\n")); + + ASSERT_IRQL(APC_LEVEL); + + if( !SocketAcquireStateLock( FCB ) ) return Status; + + FCB->ReceiveIrp.InFlightRequest = NULL; + FCB->Recv.Content = Irp->IoStatus.Information; + FCB->Recv.BytesUsed = 0; + + if( FCB->State == SOCKET_STATE_CLOSED ) { + AFD_DbgPrint(MIN_TRACE,("!!! CLOSED SOCK GOT A RECEIVE COMPLETE !!!\n")); + SocketStateUnlock( FCB ); + DestroySocket( FCB ); + return STATUS_SUCCESS; + } else if( FCB->State == SOCKET_STATE_LISTENING ) { + AFD_DbgPrint(MIN_TRACE,("!!! LISTENER GOT A RECEIVE COMPLETE !!!\n")); + SocketStateUnlock( FCB ); + return STATUS_UNSUCCESSFUL; + } + + Status = FCB->ReceiveIrp.Iosb.Status; + + if( Irp->IoStatus.Status == STATUS_SUCCESS && + Irp->IoStatus.Information == 0 ) { + AFD_DbgPrint(MID_TRACE,("Looks like an EOF\n")); + FCB->PollState |= AFD_EVENT_DISCONNECT; + } + + ReceiveActivity( FCB, NULL ); + + PollReeval( FCB->DeviceExt, FCB->FileObject ); + + SocketStateUnlock( FCB ); + AFD_DbgPrint(MID_TRACE,("Returned %x\n", Status));
return Status; @@ -274,7 +269,8 @@ FCB->State != SOCKET_STATE_CONNECTING ) { AFD_DbgPrint(MID_TRACE,("Called recv on wrong kind of socket (s%x)\n", FCB->State)); - return STATUS_UNSUCCESSFUL; + return UnlockAndMaybeComplete( FCB, STATUS_UNSUCCESSFUL, + Irp, 0, NULL, FALSE ); }
if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS ) @@ -291,57 +287,40 @@ return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0, NULL, FALSE );
+ AFD_DbgPrint(MID_TRACE,("Recv flags %x\n", RecvReq->AfdFlags)); + RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, NULL, NULL, TRUE, FALSE );
- /* Check if we're not closed down yet */ + Irp->IoStatus.Status = STATUS_PENDING; + Irp->IoStatus.Information = 0;
- if( !CantReadMore(FCB) ) { - AFD_DbgPrint(MID_TRACE,("Not EOF yet\n")); - if( FCB->ReceiveIrp.InFlightRequest ) { - AFD_DbgPrint(MID_TRACE,("We're waiting on a previous irp\n")); - Status = STATUS_PENDING; - } else { - AFD_DbgPrint(MID_TRACE,("The buffer is likely not empty\n")); - Status = STATUS_SUCCESS; - } - } else { - if( FCB->PollState & SOCKET_STATE_EOF_READ ) - Status = STATUS_END_OF_FILE; - else - Status = STATUS_SUCCESS; - - AFD_DbgPrint(MID_TRACE,("EOF Happened already\n")); - FCB->Recv.Content = 0; - FCB->Recv.BytesUsed = 0; + InsertTailList( &FCB->PendingIrpList[FUNCTION_RECV], + &Irp->Tail.Overlay.ListEntry );
- ProcessClose( FCB ); + /************ From this point, the IRP is not ours ************/
- return UnlockAndMaybeComplete - ( FCB, Status, Irp, 0, NULL, FALSE); - } - - if( NT_SUCCESS(Status) ) { - AFD_DbgPrint(MID_TRACE,("TryToSatisfy\n")); - Status = TryToSatisfyRecvRequestFromBuffer - ( FCB, RecvReq, &TotalBytesCopied ); - } + Status = ReceiveActivity( FCB, Irp );
- if( Status != STATUS_PENDING || RecvReq->AfdFlags & AFD_IMMEDIATE ) { - if( Status == STATUS_PENDING ) { - AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); - Status = STATUS_CANT_WAIT; - TotalBytesCopied = 0; - } - UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE ); - return UnlockAndMaybeComplete( FCB, Status, Irp, - TotalBytesCopied, NULL, TRUE ); - } else { + if( Status == STATUS_PENDING && RecvReq->AfdFlags & AFD_IMMEDIATE ) { + AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); + Status = STATUS_CANT_WAIT; + TotalBytesCopied = 0; + RemoveEntryList( &Irp->Tail.Overlay.ListEntry ); + UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE ); + return UnlockAndMaybeComplete( FCB, Status, Irp, + TotalBytesCopied, NULL, TRUE ); + } else if( Status == STATUS_PENDING ) { AFD_DbgPrint(MID_TRACE,("Leaving read irp\n")); - return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV ); + IoMarkIrpPending( Irp ); + } else { + AFD_DbgPrint(MID_TRACE,("Completed with status %x\n", Status)); } + + SocketStateUnlock( FCB ); + return Status; }
_____
Modified: trunk/reactos/drivers/net/afd/include/afd.h --- trunk/reactos/drivers/net/afd/include/afd.h 2005-03-11 02:38:55 UTC (rev 13921) +++ trunk/reactos/drivers/net/afd/include/afd.h 2005-03-11 07:30:17 UTC (rev 13922) @@ -132,7 +132,7 @@
} AFD_STORED_DATAGRAM, *PAFD_STORED_DATAGRAM;
typedef struct _AFD_FCB { - BOOLEAN Locked, Critical; + BOOLEAN Locked, Critical, Overread; UINT State, Flags; KIRQL OldIrql; UINT LockCount;