void *WhichConnection,
OSK_UINT NewState ) {
PCONNECTION_ENDPOINT Connection = WhichConnection;
+ ULONG OldState;
+ KIRQL OldIrql;
ASSERT_LOCKED(&TCPLock);
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;
}
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;
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)
{
exFreePool(Bucket);
}
+ Connection->SignalState &= ~SEL_WRITE;
while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
&Connection->Lock )) != NULL)
{
exFreePool(Bucket);
}
+ Connection->SignalState &= ~SEL_ACCEPT;
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
&Connection->Lock )) != NULL)
{
exFreePool(Bucket);
}
+ Connection->SignalState &= ~SEL_CONNECT;
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest,
&Connection->Lock )) != NULL)
{
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 ) {
IsListEmpty(&Connection->ListenRequest) ?
"empty" : "nonempty"));
+ Connection->SignalState &= ~SEL_ACCEPT;
while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
&Connection->Lock )) != NULL ) {
PIO_STACK_LOCATION IrpSp;
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 {
IsListEmpty(&Connection->ReceiveRequest) ?
"empty" : "nonempty"));
+ Connection->SignalState &= ~SEL_READ;
while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
&Connection->Lock )) != NULL ) {
OSK_UINT RecvLen = 0, Received = 0;
} else if( Status == STATUS_PENDING ) {
ExInterlockedInsertHeadList
( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock );
+ Connection->SignalState |= SEL_READ;
break;
} else {
TI_DbgPrint(DEBUG_TCP,
IsListEmpty(&Connection->SendRequest) ?
"empty" : "nonempty"));
+ Connection->SignalState &= ~SEL_WRITE;
while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
&Connection->Lock )) != NULL ) {
OSK_UINT SendLen = 0, Sent = 0;
} else if( Status == STATUS_PENDING ) {
ExInterlockedInsertHeadList
( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock );
+ Connection->SignalState |= SEL_WRITE;
break;
} else {
TI_DbgPrint(DEBUG_TCP,
}
}
- 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 ) {
IPPacket->TotalSize,
IPPacket->HeaderSize );
- DrainSignals();
-
TcpipRecursiveMutexLeave( &TCPLock );
}