Convert per-process hostent, servent and protent buffers into

per-thread buffers.
This commit is contained in:
Robert Shearman 2004-12-22 18:23:49 +00:00 committed by Alexandre Julliard
parent 98511484c7
commit c7d80ccf52

View File

@ -214,9 +214,20 @@ typedef struct /* WSAAsyncSelect() control struct */
#define WS_MAX_UDP_DATAGRAM 1024 #define WS_MAX_UDP_DATAGRAM 1024
static INT WINAPI WSA_DefaultBlockingHook( FARPROC x ); static INT WINAPI WSA_DefaultBlockingHook( FARPROC x );
static struct WS_hostent *he_buffer; /* typecast for Win32 ws_hostent */ /* hostent's, servent's and protent's are stored in one buffer per thread,
static struct WS_servent *se_buffer; /* typecast for Win32 ws_servent */ * as documented on MSDN for the functions that return any of the buffers */
static struct WS_protoent *pe_buffer; /* typecast for Win32 ws_protoent */ struct per_thread_data
{
int opentype;
struct WS_hostent *he_buffer;
struct WS_servent *se_buffer;
struct WS_protoent *pe_buffer;
int he_len;
int se_len;
int pe_len;
};
static DWORD tls_index = TLS_OUT_OF_INDEXES; /* TLS index for per-thread data */
static INT num_startup; /* reference counter */ static INT num_startup; /* reference counter */
static FARPROC blocking_hook = WSA_DefaultBlockingHook; static FARPROC blocking_hook = WSA_DefaultBlockingHook;
@ -279,8 +290,6 @@ static const int ws_ip_map[][2] =
{ 0, 0 } { 0, 0 }
}; };
static DWORD opentype_tls_index = TLS_OUT_OF_INDEXES; /* TLS index for SO_OPENTYPE flag */
inline static DWORD NtStatusToWSAError ( const DWORD status ) inline static DWORD NtStatusToWSAError ( const DWORD status )
{ {
/* We only need to cover the status codes set by server async request handling */ /* We only need to cover the status codes set by server async request handling */
@ -399,17 +408,33 @@ static int _get_sock_error(SOCKET s, unsigned int bit)
return events[bit]; return events[bit];
} }
static void WINSOCK_DeleteIData(void) static struct per_thread_data *get_per_thread_data(void)
{ {
/* delete scratch buffers */ struct per_thread_data * ptb = TlsGetValue( tls_index );
/* lazy initialization */
if (!ptb)
{
ptb = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptb) );
TlsSetValue( tls_index, ptb );
}
return ptb;
}
if (he_buffer) HeapFree( GetProcessHeap(), 0, he_buffer ); static void free_per_thread_data(void)
if (se_buffer) HeapFree( GetProcessHeap(), 0, se_buffer ); {
if (pe_buffer) HeapFree( GetProcessHeap(), 0, pe_buffer ); struct per_thread_data * ptb = TlsGetValue( tls_index );
he_buffer = NULL;
se_buffer = NULL; if (!ptb) return;
pe_buffer = NULL;
num_startup = 0; /* delete scratch buffers */
HeapFree( GetProcessHeap(), 0, ptb->he_buffer );
HeapFree( GetProcessHeap(), 0, ptb->se_buffer );
HeapFree( GetProcessHeap(), 0, ptb->pe_buffer );
ptb->he_buffer = NULL;
ptb->se_buffer = NULL;
ptb->pe_buffer = NULL;
HeapFree( GetProcessHeap(), 0, ptb );
} }
/*********************************************************************** /***********************************************************************
@ -420,13 +445,16 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad)
TRACE("%p 0x%lx %p\n", hInstDLL, fdwReason, fImpLoad); TRACE("%p 0x%lx %p\n", hInstDLL, fdwReason, fImpLoad);
switch (fdwReason) { switch (fdwReason) {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hInstDLL); tls_index = TlsAlloc();
opentype_tls_index = TlsAlloc();
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
TlsFree( opentype_tls_index ); free_per_thread_data();
WINSOCK_DeleteIData(); TlsFree( tls_index );
break; num_startup = 0;
break;
case DLL_THREAD_DETACH:
free_per_thread_data();
break;
} }
return TRUE; return TRUE;
} }
@ -678,11 +706,7 @@ int WINAPI WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)
INT WINAPI WSACleanup(void) INT WINAPI WSACleanup(void)
{ {
if (num_startup) if (num_startup)
{
if (--num_startup > 0) return 0;
WINSOCK_DeleteIData();
return 0; return 0;
}
SetLastError(WSANOTINITIALISED); SetLastError(WSANOTINITIALISED);
return SOCKET_ERROR; return SOCKET_ERROR;
} }
@ -706,41 +730,41 @@ void WINAPI WSASetLastError(INT iError) {
static struct WS_hostent *check_buffer_he(int size) static struct WS_hostent *check_buffer_he(int size)
{ {
static int he_len; struct per_thread_data * ptb = get_per_thread_data();
if (he_buffer) if (ptb->he_buffer)
{ {
if (he_len >= size ) return he_buffer; if (ptb->he_len >= size ) return ptb->he_buffer;
HeapFree( GetProcessHeap(), 0, he_buffer ); HeapFree( GetProcessHeap(), 0, ptb->he_buffer );
} }
he_buffer = HeapAlloc( GetProcessHeap(), 0, (he_len = size) ); ptb->he_buffer = HeapAlloc( GetProcessHeap(), 0, (ptb->he_len = size) );
if (!he_buffer) SetLastError(WSAENOBUFS); if (!ptb->he_buffer) SetLastError(WSAENOBUFS);
return he_buffer; return ptb->he_buffer;
} }
static struct WS_servent *check_buffer_se(int size) static struct WS_servent *check_buffer_se(int size)
{ {
static int se_len; struct per_thread_data * ptb = get_per_thread_data();
if (se_buffer) if (ptb->se_buffer)
{ {
if (se_len >= size ) return se_buffer; if (ptb->se_len >= size ) return ptb->se_buffer;
HeapFree( GetProcessHeap(), 0, se_buffer ); HeapFree( GetProcessHeap(), 0, ptb->se_buffer );
} }
se_buffer = HeapAlloc( GetProcessHeap(), 0, (se_len = size) ); ptb->se_buffer = HeapAlloc( GetProcessHeap(), 0, (ptb->se_len = size) );
if (!se_buffer) SetLastError(WSAENOBUFS); if (!ptb->se_buffer) SetLastError(WSAENOBUFS);
return se_buffer; return ptb->se_buffer;
} }
static struct WS_protoent *check_buffer_pe(int size) static struct WS_protoent *check_buffer_pe(int size)
{ {
static int pe_len; struct per_thread_data * ptb = get_per_thread_data();
if (pe_buffer) if (ptb->pe_buffer)
{ {
if (pe_len >= size ) return pe_buffer; if (ptb->pe_len >= size ) return ptb->pe_buffer;
HeapFree( GetProcessHeap(), 0, pe_buffer ); HeapFree( GetProcessHeap(), 0, ptb->pe_buffer );
} }
pe_buffer = HeapAlloc( GetProcessHeap(), 0, (pe_len = size) ); ptb->pe_buffer = HeapAlloc( GetProcessHeap(), 0, (ptb->pe_len = size) );
if (!pe_buffer) SetLastError(WSAENOBUFS); if (!ptb->pe_buffer) SetLastError(WSAENOBUFS);
return pe_buffer; return ptb->pe_buffer;
} }
/* ----------------------------------- i/o APIs */ /* ----------------------------------- i/o APIs */
@ -1600,7 +1624,7 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level,
SetLastError(WSAEFAULT); SetLastError(WSAEFAULT);
return SOCKET_ERROR; return SOCKET_ERROR;
} }
*(int *)optval = (int)TlsGetValue( opentype_tls_index ); *(int *)optval = get_per_thread_data()->opentype;
*optlen = sizeof(int); *optlen = sizeof(int);
TRACE("getting global SO_OPENTYPE = 0x%x\n", *((int*)optval) ); TRACE("getting global SO_OPENTYPE = 0x%x\n", *((int*)optval) );
return 0; return 0;
@ -2390,7 +2414,7 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname,
SetLastError(WSAEFAULT); SetLastError(WSAEFAULT);
return SOCKET_ERROR; return SOCKET_ERROR;
} }
TlsSetValue( opentype_tls_index, (LPVOID)*(int *)optval ); get_per_thread_data()->opentype = *(int *)optval;
TRACE("setting global SO_OPENTYPE to 0x%x\n", *(int *)optval ); TRACE("setting global SO_OPENTYPE to 0x%x\n", *(int *)optval );
return 0; return 0;
} }
@ -2617,7 +2641,7 @@ SOCKET WINAPI WS_socket(int af, int type, int protocol)
TRACE("af=%d type=%d protocol=%d\n", af, type, protocol); TRACE("af=%d type=%d protocol=%d\n", af, type, protocol);
return WSASocketA ( af, type, protocol, NULL, 0, return WSASocketA ( af, type, protocol, NULL, 0,
(TlsGetValue(opentype_tls_index) ? 0 : WSA_FLAG_OVERLAPPED) ); get_per_thread_data()->opentype ? 0 : WSA_FLAG_OVERLAPPED );
} }