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;