mirror of
https://github.com/reactos/reactos.git
synced 2024-09-13 06:11:59 +00:00
[IP/lwIP]
- Fix graceful closure hanging bug svn path=/branches/GSoC_2011/TcpIpDriver/; revision=52594
This commit is contained in:
parent
00612e723d
commit
9f0c4d27d8
|
@ -90,11 +90,18 @@ FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status)
|
||||||
Bucket->Status = Status;
|
Bucket->Status = Status;
|
||||||
Bucket->Information = 0;
|
Bucket->Information = 0;
|
||||||
|
|
||||||
CompleteBucket(Connection, Bucket, TRUE);
|
CompleteBucket(Connection, Bucket, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calling with Status == STATUS_SUCCESS means that we got a graceful closure
|
||||||
|
* so we don't want to kill everything else since send is still valid in this state
|
||||||
|
*/
|
||||||
if (Status == STATUS_SUCCESS)
|
if (Status == STATUS_SUCCESS)
|
||||||
Status = STATUS_FILE_CLOSED;
|
{
|
||||||
|
DbgPrint("[IP, FlushAllQueues] Flushed recv only after graceful closure\n");
|
||||||
|
DereferenceObject(Connection);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while ((Entry = ExInterlockedRemoveHeadList(&Connection->ListenRequest, &Connection->Lock)))
|
while ((Entry = ExInterlockedRemoveHeadList(&Connection->ListenRequest, &Connection->Lock)))
|
||||||
{
|
{
|
||||||
|
@ -106,7 +113,7 @@ FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status)
|
||||||
DbgPrint("[IP, FlushAllQueues] Completing Listen request for Connection = 0x%x\n", Bucket->AssociatedEndpoint);
|
DbgPrint("[IP, FlushAllQueues] Completing Listen request for Connection = 0x%x\n", Bucket->AssociatedEndpoint);
|
||||||
|
|
||||||
DereferenceObject(Bucket->AssociatedEndpoint);
|
DereferenceObject(Bucket->AssociatedEndpoint);
|
||||||
CompleteBucket(Connection, Bucket, TRUE);
|
CompleteBucket(Connection, Bucket, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((Entry = ExInterlockedRemoveHeadList(&Connection->SendRequest, &Connection->Lock)))
|
while ((Entry = ExInterlockedRemoveHeadList(&Connection->SendRequest, &Connection->Lock)))
|
||||||
|
@ -120,7 +127,7 @@ FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status)
|
||||||
Bucket->Status = Status;
|
Bucket->Status = Status;
|
||||||
Bucket->Information = 0;
|
Bucket->Information = 0;
|
||||||
|
|
||||||
CompleteBucket(Connection, Bucket, TRUE);
|
CompleteBucket(Connection, Bucket, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest, &Connection->Lock)))
|
while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest, &Connection->Lock)))
|
||||||
|
@ -132,7 +139,7 @@ FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status)
|
||||||
|
|
||||||
DbgPrint("[IP, FlushAllQueues] Completing Connection request for Connection = 0x%x\n", Bucket->AssociatedEndpoint);
|
DbgPrint("[IP, FlushAllQueues] Completing Connection request for Connection = 0x%x\n", Bucket->AssociatedEndpoint);
|
||||||
|
|
||||||
CompleteBucket(Connection, Bucket, TRUE);
|
CompleteBucket(Connection, Bucket, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
DereferenceObject(Connection);
|
DereferenceObject(Connection);
|
||||||
|
@ -145,8 +152,12 @@ TCPFinEventHandler(void *arg, err_t err)
|
||||||
{
|
{
|
||||||
PCONNECTION_ENDPOINT Connection = arg;
|
PCONNECTION_ENDPOINT Connection = arg;
|
||||||
|
|
||||||
/* We're already closed so we don't want to call lwip_close */
|
/* Only clear the pointer if the shutdown was caused by an error */
|
||||||
Connection->SocketContext = NULL;
|
if (err != ERR_OK)
|
||||||
|
{
|
||||||
|
/* We're already closed by the error so we don't want to call lwip_close */
|
||||||
|
Connection->SocketContext = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
DbgPrint("[IP, TCPFinEventHandler] Called for Connection( 0x%x )-> SocketContext = pcb (0x%x)\n", Connection, Connection->SocketContext);
|
DbgPrint("[IP, TCPFinEventHandler] Called for Connection( 0x%x )-> SocketContext = pcb (0x%x)\n", Connection, Connection->SocketContext);
|
||||||
|
|
||||||
|
|
|
@ -127,8 +127,11 @@ InternalRecvEventHandler(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t e
|
||||||
}
|
}
|
||||||
else if (err == ERR_OK)
|
else if (err == ERR_OK)
|
||||||
{
|
{
|
||||||
|
/* Complete pending reads with 0 bytes to indicate a graceful closure,
|
||||||
|
* but note that send is still possible in this state so we don't close the
|
||||||
|
* whole socket here (by calling tcp_close()) as that would violate TCP specs
|
||||||
|
*/
|
||||||
TCPFinEventHandler(arg, ERR_OK);
|
TCPFinEventHandler(arg, ERR_OK);
|
||||||
tcp_close(pcb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgPrint("[lwIP, InternalRecvEventHandler] Done ERR_OK 3\n");
|
DbgPrint("[lwIP, InternalRecvEventHandler] Done ERR_OK 3\n");
|
||||||
|
|
Loading…
Reference in a new issue