Convert per-process hostent, servent and protent buffers into
per-thread buffers.
This commit is contained in:
parent
98511484c7
commit
c7d80ccf52
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user