- Rework our oskittcp signalling

- SignalledConnectionsList is now only used for connections that have pending requests
 - Remove another unused member from CONNECTION_ENDPOINT

svn path=/trunk/; revision=43926
This commit is contained in:
Cameron Gutman 2009-11-02 21:28:25 +00:00
parent 78ce662964
commit 99fec75b6f
4 changed files with 52 additions and 19 deletions

View file

@ -105,6 +105,7 @@ NTSTATUS TCPAccept
PVOID Context );
/* tcp.c */
ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection );
PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext );
VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection );

View file

@ -309,7 +309,6 @@ typedef struct _CONNECTION_ENDPOINT {
LIST_ENTRY SignalList; /* Entry in the list of sockets waiting for
* notification service to the client */
UINT SignalState; /* Active signals from oskit */
BOOLEAN Signalled; /* Are we a member of the signal list */
} CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;

View file

@ -15,6 +15,8 @@ int TCPSocketState(void *ClientData,
void *WhichConnection,
OSK_UINT NewState ) {
PCONNECTION_ENDPOINT Connection = WhichConnection;
ULONG OldState;
KIRQL OldIrql;
ASSERT_LOCKED(&TCPLock);
@ -38,14 +40,23 @@ int TCPSocketState(void *ClientData,
TI_DbgPrint(DEBUG_TCP,("Found socket %x\n", Connection));
}
TI_DbgPrint(MID_TRACE,("Connection signalled: %d\n",
Connection->Signalled));
OldState = Connection->SignalState;
Connection->SignalState |= NewState;
if( !Connection->Signalled ) {
Connection->Signalled = TRUE;
ExInterlockedInsertTailList( &SignalledConnectionsList, &Connection->SignalList, &SignalledConnectionsLock );
NewState = HandleSignalledConnection(Connection);
KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql);
if ((NewState == 0 || NewState == SEL_FIN) &&
(OldState != 0 && OldState != SEL_FIN))
{
RemoveEntryList(&Connection->SignalList);
}
else if (NewState != 0 && NewState != SEL_FIN)
{
InsertTailList(&SignalledConnectionsList, &Connection->SignalList);
}
KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql);
return 0;
}

View file

@ -22,7 +22,7 @@ FAST_MUTEX SleepingThreadsLock;
RECURSIVE_MUTEX TCPLock;
PORT_SET TCPPorts;
static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
NTSTATUS Status = STATUS_SUCCESS;
PTCP_COMPLETION_ROUTINE Complete;
PTDI_BUCKET Bucket;
@ -38,6 +38,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
if( Connection->SignalState & SEL_FIN ) {
TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n"));
Connection->SignalState &= ~SEL_READ;
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
&Connection->Lock )) != NULL)
{
@ -49,6 +50,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
exFreePool(Bucket);
}
Connection->SignalState &= ~SEL_WRITE;
while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
&Connection->Lock )) != NULL)
{
@ -60,6 +62,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
exFreePool(Bucket);
}
Connection->SignalState &= ~SEL_ACCEPT;
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
&Connection->Lock )) != NULL)
{
@ -75,6 +78,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
exFreePool(Bucket);
}
Connection->SignalState &= ~SEL_CONNECT;
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest,
&Connection->Lock )) != NULL)
{
@ -85,12 +89,11 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
exFreePool(Bucket);
}
Connection->SignalState = 0;
}
/* Things that can happen when we try the initial connection */
if( Connection->SignalState & SEL_CONNECT ) {
Connection->SignalState &= ~SEL_CONNECT;
while( (Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest,
&Connection->Lock )) != NULL ) {
@ -118,6 +121,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
IsListEmpty(&Connection->ListenRequest) ?
"empty" : "nonempty"));
Connection->SignalState &= ~SEL_ACCEPT;
while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
&Connection->Lock )) != NULL ) {
PIO_STACK_LOCATION IrpSp;
@ -137,6 +141,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n"));
if( Status == STATUS_PENDING ) {
Connection->SignalState |= SEL_ACCEPT;
ExInterlockedInsertHeadList( &Connection->ListenRequest, &Bucket->Entry, &Connection->Lock );
break;
} else {
@ -152,6 +157,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
IsListEmpty(&Connection->ReceiveRequest) ?
"empty" : "nonempty"));
Connection->SignalState &= ~SEL_READ;
while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
&Connection->Lock )) != NULL ) {
OSK_UINT RecvLen = 0, Received = 0;
@ -197,6 +203,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
} else if( Status == STATUS_PENDING ) {
ExInterlockedInsertHeadList
( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock );
Connection->SignalState |= SEL_READ;
break;
} else {
TI_DbgPrint(DEBUG_TCP,
@ -212,6 +219,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
IsListEmpty(&Connection->SendRequest) ?
"empty" : "nonempty"));
Connection->SignalState &= ~SEL_WRITE;
while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
&Connection->Lock )) != NULL ) {
OSK_UINT SendLen = 0, Sent = 0;
@ -256,6 +264,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
} else if( Status == STATUS_PENDING ) {
ExInterlockedInsertHeadList
( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock );
Connection->SignalState |= SEL_WRITE;
break;
} else {
TI_DbgPrint(DEBUG_TCP,
@ -267,20 +276,35 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
}
}
Connection->SignalState = 0;
Connection->Signalled = FALSE;
return Connection->SignalState;
}
VOID DrainSignals() {
static VOID DrainSignals() {
PCONNECTION_ENDPOINT Connection;
PLIST_ENTRY ListEntry;
PLIST_ENTRY CurrentEntry, NextEntry;
ULONG NewState;
KIRQL OldIrql;
while( (ListEntry = ExInterlockedRemoveHeadList(&SignalledConnectionsList,
&SignalledConnectionsLock)) != NULL) {
Connection = CONTAINING_RECORD( ListEntry, CONNECTION_ENDPOINT,
KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql);
CurrentEntry = SignalledConnectionsList.Flink;
while (CurrentEntry != &SignalledConnectionsList)
{
NextEntry = CurrentEntry->Flink;
Connection = CONTAINING_RECORD( CurrentEntry, CONNECTION_ENDPOINT,
SignalList );
HandleSignalledConnection( Connection );
KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql);
NewState = HandleSignalledConnection(Connection);
KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql);
if (NewState == SEL_FIN || NewState == 0)
{
RemoveEntryList(CurrentEntry);
}
CurrentEntry = NextEntry;
}
KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql);
}
PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) {
@ -354,8 +378,6 @@ VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
IPPacket->TotalSize,
IPPacket->HeaderSize );
DrainSignals();
TcpipRecursiveMutexLeave( &TCPLock );
}