- Use a linked list to store the socket information instead of allocating a massive array (1024 elements!) for each process in DllMain to hold all of the pointers
- Fix a massive memory leak (free the socket information which we leaked for every socket we allocated)
- This improves performance because we don't have to look through an array of stale socket information pointers (which we never actually removed from the socket information array in the old code) and the new code queues the socket information at the head of the list which makes newer sockets faster to access

svn path=/trunk/; revision=47646
This commit is contained in:
Cameron Gutman 2010-06-07 00:24:27 +00:00
parent 0b3f90dce4
commit e0549f6100
2 changed files with 39 additions and 15 deletions

View file

@ -23,7 +23,7 @@ HANDLE GlobalHeap;
WSPUPCALLTABLE Upcalls;
LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest;
ULONG SocketCount = 0;
PSOCKET_INFORMATION *Sockets = NULL;
PSOCKET_INFORMATION SocketListHead = NULL;
LIST_ENTRY SockHelpersListHead = { NULL, NULL };
ULONG SockAsyncThreadRefCount;
HANDLE SockAsyncHelperAfdHandle;
@ -292,8 +292,8 @@ WSPSocket(int AddressFamily,
NULL);
/* Save in Process Sockets List */
Sockets[SocketCount] = Socket;
SocketCount ++;
Socket->NextSocket = SocketListHead;
SocketListHead = Socket;
/* Create the Socket Context */
CreateContext(Socket);
@ -423,7 +423,7 @@ WSPCloseSocket(IN SOCKET Handle,
OUT LPINT lpErrno)
{
IO_STATUS_BLOCK IoStatusBlock;
PSOCKET_INFORMATION Socket = NULL;
PSOCKET_INFORMATION Socket = NULL, CurrentSocket;
NTSTATUS Status;
HANDLE SockEvent;
AFD_DISCONNECT_INFO DisconnectInfo;
@ -562,6 +562,27 @@ WSPCloseSocket(IN SOCKET Handle,
NtClose(Socket->TdiConnectionHandle);
Socket->TdiConnectionHandle = NULL;
if (SocketListHead == Socket)
{
SocketListHead = SocketListHead->NextSocket;
}
else
{
CurrentSocket = SocketListHead;
while (CurrentSocket->NextSocket)
{
if (CurrentSocket->NextSocket == Socket)
{
CurrentSocket->NextSocket = CurrentSocket->NextSocket->NextSocket;
break;
}
CurrentSocket = CurrentSocket->NextSocket;
}
}
HeapFree(GlobalHeap, 0, Socket);
/* Close the handle */
NtClose((HANDLE)Handle);
NtClose(SockEvent);
@ -2244,16 +2265,22 @@ SetSocketInformation(PSOCKET_INFORMATION Socket,
PSOCKET_INFORMATION
GetSocketStructure(SOCKET Handle)
{
ULONG i;
PSOCKET_INFORMATION CurrentSocket;
for (i=0; i<SocketCount; i++)
/* This is a special case */
if (SocketListHead->Handle == Handle)
return SocketListHead;
CurrentSocket = SocketListHead;
while (CurrentSocket->NextSocket)
{
if (Sockets[i]->Handle == Handle)
{
return Sockets[i];
}
if (CurrentSocket->Handle == Handle)
return CurrentSocket;
CurrentSocket = CurrentSocket->NextSocket;
}
return 0;
return NULL;
}
int CreateContext(PSOCKET_INFORMATION Socket)
@ -2771,10 +2798,6 @@ DllMain(HANDLE hInstDll,
/* Heap to use when allocating */
GlobalHeap = GetProcessHeap();
/* Allocate Heap for 1024 Sockets, can be expanded later */
Sockets = HeapAlloc(GetProcessHeap(), 0, sizeof(PSOCKET_INFORMATION) * 1024);
if (!Sockets) return FALSE;
AFD_DbgPrint(MAX_TRACE, ("MSAFD.DLL has been loaded\n"));
break;

View file

@ -100,6 +100,7 @@ typedef struct _SOCKET_INFORMATION {
BOOL TrySAN;
SOCKADDR WSLocalAddress;
SOCKADDR WSRemoteAddress;
struct _SOCKET_INFORMATION *NextSocket;
} SOCKET_INFORMATION, *PSOCKET_INFORMATION;