Author: cgutman
Date: Wed Jun 9 06:45:17 2010
New Revision: 47704
URL:
http://svn.reactos.org/svn/reactos?rev=47704&view=rev
Log:
[IP]
- Handle socket operations that can be completed immediately before terminating the socket
to avoid losing data sitting in the receive buffer
Modified:
trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c
Modified: trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/t…
==============================================================================
--- trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] Wed Jun 9 06:45:17
2010
@@ -25,7 +25,6 @@
NTSTATUS Status;
PIRP Irp;
PMDL Mdl;
- ULONG SocketError = 0;
KIRQL OldIrql;
PTCP_COMPLETION_ROUTINE Complete;
@@ -34,69 +33,6 @@
TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n",
Connection, Connection->SocketContext));
-
- if( Connection->SignalState & SEL_FIN ) {
- TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n"));
-
- /* If OskitTCP initiated the disconnect, try to read the socket error that
occurred */
- if (Connection->SocketContext)
- SocketError =
TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext));
-
- /* Default to STATUS_CANCELLED if we initiated the disconnect or no socket
error was reported */
- if (!Connection->SocketContext || !SocketError)
- SocketError = STATUS_CANCELLED;
-
- while (!IsListEmpty(&Connection->ReceiveRequest))
- {
- Entry = RemoveHeadList( &Connection->ReceiveRequest );
-
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
- Bucket->Status = SocketError;
- Bucket->Information = 0;
-
- InsertTailList(&Connection->CompletionQueue,
&Bucket->Entry);
- }
-
- while (!IsListEmpty(&Connection->SendRequest))
- {
- Entry = RemoveHeadList( &Connection->SendRequest );
-
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
- Bucket->Status = SocketError;
- Bucket->Information = 0;
-
- InsertTailList(&Connection->CompletionQueue,
&Bucket->Entry);
- }
-
- while (!IsListEmpty(&Connection->ListenRequest))
- {
- Entry = RemoveHeadList( &Connection->ListenRequest );
-
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
- Bucket->Status = SocketError;
- Bucket->Information = 0;
- DereferenceObject(Bucket->AssociatedEndpoint);
-
- InsertTailList(&Connection->CompletionQueue,
&Bucket->Entry);
- }
-
- while (!IsListEmpty(&Connection->ConnectRequest))
- {
- Entry = RemoveHeadList( &Connection->ConnectRequest );
-
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
- Bucket->Status = SocketError;
- Bucket->Information = 0;
-
- InsertTailList(&Connection->CompletionQueue,
&Bucket->Entry);
- }
-
- Connection->SignalState = SEL_FIN;
- }
/* Things that can happen when we try the initial connection */
if( Connection->SignalState & SEL_CONNECT ) {
@@ -140,11 +76,11 @@
TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n"));
- if( Status == STATUS_PENDING ) {
+ if( Status == STATUS_PENDING && !(Connection->SignalState &
SEL_FIN) ) {
InsertHeadList( &Connection->ListenRequest,
&Bucket->Entry );
break;
} else {
- Bucket->Status = Status;
+ Bucket->Status = (Status == STATUS_PENDING) ? STATUS_CANCELLED :
Status;
Bucket->Information = 0;
DereferenceObject(Bucket->AssociatedEndpoint);
@@ -194,7 +130,7 @@
TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
- if( Status == STATUS_PENDING ) {
+ if( Status == STATUS_PENDING && !(Connection->SignalState &
SEL_FIN) ) {
InsertHeadList( &Connection->ReceiveRequest,
&Bucket->Entry );
break;
} else {
@@ -202,8 +138,8 @@
("Completing Receive request: %x %x\n",
Bucket->Request, Status));
- Bucket->Status = Status;
- Bucket->Information = (Status == STATUS_SUCCESS) ? Received : 0;
+ Bucket->Status = (Status == STATUS_PENDING) ? STATUS_CANCELLED :
Status;
+ Bucket->Information = (Bucket->Status == STATUS_SUCCESS) ?
Received : 0;
InsertTailList(&Connection->CompletionQueue,
&Bucket->Entry);
}
@@ -248,7 +184,7 @@
TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent));
- if( Status == STATUS_PENDING ) {
+ if( Status == STATUS_PENDING && !(Connection->SignalState &
SEL_FIN) ) {
InsertHeadList( &Connection->SendRequest, &Bucket->Entry
);
break;
} else {
@@ -256,8 +192,8 @@
("Completing Send request: %x %x\n",
Bucket->Request, Status));
- Bucket->Status = Status;
- Bucket->Information = (Status == STATUS_SUCCESS) ? Sent : 0;
+ Bucket->Status = (Status == STATUS_PENDING) ? STATUS_CANCELLED :
Status;
+ Bucket->Information = (Bucket->Status == STATUS_SUCCESS) ? Sent
: 0;
InsertTailList(&Connection->CompletionQueue,
&Bucket->Entry);
}
@@ -737,7 +673,7 @@
Connection->SocketContext = NULL;
/* Don't try to close again if the other side closed us already */
- if (Connection->SignalState != SEL_FIN)
+ if (!(Connection->SignalState & SEL_FIN))
{
/* We need to close here otherwise oskit will never indicate
* SEL_FIN and we will never fully close the connection */