Commit d638653f authored by Sebastian Lackner's avatar Sebastian Lackner Committed by Alexandre Julliard

ws2_32: Do not spawn a separate thread for each async task.

parent 58f944bb
...@@ -52,6 +52,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(winsock); ...@@ -52,6 +52,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(winsock);
struct async_query_header struct async_query_header
{ {
LPARAM (*func)( struct async_query_header *query );
HWND hWnd; HWND hWnd;
UINT uMsg; UINT uMsg;
void *sbuf; void *sbuf;
...@@ -128,13 +129,6 @@ static int list_dup(char** l_src, char* ref, int item_size) ...@@ -128,13 +129,6 @@ static int list_dup(char** l_src, char* ref, int item_size)
return (p - ref); return (p - ref);
} }
static DWORD finish_query( struct async_query_header *query, LPARAM lparam )
{
PostMessageW( query->hWnd, query->uMsg, (WPARAM)query->handle, lparam );
HeapFree( GetProcessHeap(), 0, query );
return 0;
}
/* ----- hostent */ /* ----- hostent */
static LPARAM copy_he(void *base, int size, const struct WS_hostent *he) static LPARAM copy_he(void *base, int size, const struct WS_hostent *he)
...@@ -162,20 +156,20 @@ static LPARAM copy_he(void *base, int size, const struct WS_hostent *he) ...@@ -162,20 +156,20 @@ static LPARAM copy_he(void *base, int size, const struct WS_hostent *he)
return MAKELPARAM( needed, 0 ); return MAKELPARAM( needed, 0 );
} }
static DWORD WINAPI async_gethostbyname(LPVOID arg) static LPARAM async_gethostbyname( struct async_query_header *query )
{ {
struct async_query_gethostbyname *aq = arg; struct async_query_gethostbyname *aq = CONTAINING_RECORD( query, struct async_query_gethostbyname, query );
struct WS_hostent *he = WS_gethostbyname( aq->host_name ); struct WS_hostent *he = WS_gethostbyname( aq->host_name );
return finish_query( &aq->query, copy_he( aq->query.sbuf, aq->query.sbuflen, he )); return copy_he( query->sbuf, query->sbuflen, he );
} }
static DWORD WINAPI async_gethostbyaddr(LPVOID arg) static LPARAM async_gethostbyaddr( struct async_query_header *query )
{ {
struct async_query_gethostbyaddr *aq = arg; struct async_query_gethostbyaddr *aq = CONTAINING_RECORD( query, struct async_query_gethostbyaddr, query );
struct WS_hostent *he = WS_gethostbyaddr( aq->host_addr, aq->host_len, aq->host_type ); struct WS_hostent *he = WS_gethostbyaddr( aq->host_addr, aq->host_len, aq->host_type );
return finish_query( &aq->query, copy_he( aq->query.sbuf, aq->query.sbuflen, he )); return copy_he( query->sbuf, query->sbuflen, he );
} }
/* ----- protoent */ /* ----- protoent */
...@@ -200,20 +194,20 @@ static LPARAM copy_pe(void *base, int size, const struct WS_protoent* pe) ...@@ -200,20 +194,20 @@ static LPARAM copy_pe(void *base, int size, const struct WS_protoent* pe)
return MAKELPARAM( needed, 0 ); return MAKELPARAM( needed, 0 );
} }
static DWORD WINAPI async_getprotobyname(LPVOID arg) static LPARAM async_getprotobyname( struct async_query_header *query )
{ {
struct async_query_getprotobyname *aq = arg; struct async_query_getprotobyname *aq = CONTAINING_RECORD( query, struct async_query_getprotobyname, query );
struct WS_protoent *pe = WS_getprotobyname( aq->proto_name ); struct WS_protoent *pe = WS_getprotobyname( aq->proto_name );
return finish_query( &aq->query, copy_pe( aq->query.sbuf, aq->query.sbuflen, pe )); return copy_pe( query->sbuf, query->sbuflen, pe );
} }
static DWORD WINAPI async_getprotobynumber(LPVOID arg) static LPARAM async_getprotobynumber( struct async_query_header *query )
{ {
struct async_query_getprotobynumber *aq = arg; struct async_query_getprotobynumber *aq = CONTAINING_RECORD( query, struct async_query_getprotobynumber, query );
struct WS_protoent *pe = WS_getprotobynumber( aq->proto_number ); struct WS_protoent *pe = WS_getprotobynumber( aq->proto_number );
return finish_query( &aq->query, copy_pe( aq->query.sbuf, aq->query.sbuflen, pe )); return copy_pe( query->sbuf, query->sbuflen, pe );
} }
/* ----- servent */ /* ----- servent */
...@@ -240,20 +234,29 @@ static LPARAM copy_se(void *base, int size, const struct WS_servent* se) ...@@ -240,20 +234,29 @@ static LPARAM copy_se(void *base, int size, const struct WS_servent* se)
return MAKELPARAM( needed, 0 ); return MAKELPARAM( needed, 0 );
} }
static DWORD WINAPI async_getservbyname(LPVOID arg) static LPARAM async_getservbyname( struct async_query_header *query )
{ {
struct async_query_getservbyname *aq = arg; struct async_query_getservbyname *aq = CONTAINING_RECORD( query, struct async_query_getservbyname, query );
struct WS_servent *se = WS_getservbyname( aq->serv_name, aq->serv_proto ); struct WS_servent *se = WS_getservbyname( aq->serv_name, aq->serv_proto );
return finish_query( &aq->query, copy_se( aq->query.sbuf, aq->query.sbuflen, se )); return copy_se( query->sbuf, query->sbuflen, se );
} }
static DWORD WINAPI async_getservbyport(LPVOID arg) static LPARAM async_getservbyport( struct async_query_header *query )
{ {
struct async_query_getservbyport *aq = arg; struct async_query_getservbyport *aq = CONTAINING_RECORD( query, struct async_query_getservbyport, query );
struct WS_servent *se = WS_getservbyport( aq->serv_port, aq->serv_proto ); struct WS_servent *se = WS_getservbyport( aq->serv_port, aq->serv_proto );
return finish_query( &aq->query, copy_se( aq->query.sbuf, aq->query.sbuflen, se )); return copy_se( query->sbuf, query->sbuflen, se );
}
static void WINAPI async_worker( TP_CALLBACK_INSTANCE *instance, void *context )
{
struct async_query_header *query = context;
LPARAM lparam = query->func( query );
PostMessageW( query->hWnd, query->uMsg, (WPARAM)query->handle, lparam );
HeapFree( GetProcessHeap(), 0, query );
} }
...@@ -264,30 +267,28 @@ static DWORD WINAPI async_getservbyport(LPVOID arg) ...@@ -264,30 +267,28 @@ static DWORD WINAPI async_getservbyport(LPVOID arg)
* with no thread support. This relies on the fact that PostMessage() does * with no thread support. This relies on the fact that PostMessage() does
* not actually call the windowproc before the function returns. * not actually call the windowproc before the function returns.
*/ */
static HANDLE run_query( HWND hWnd, UINT uMsg, LPTHREAD_START_ROUTINE func, static HANDLE run_query( HWND hWnd, UINT uMsg, LPARAM (*func)(struct async_query_header *),
struct async_query_header *query, void *sbuf, INT sbuflen ) struct async_query_header *query, void *sbuf, INT sbuflen )
{ {
static LONG next_handle = 0xdead; static LONG next_handle = 0xdead;
HANDLE thread;
ULONG handle; ULONG handle;
do do
handle = LOWORD( InterlockedIncrement( &next_handle )); handle = LOWORD( InterlockedIncrement( &next_handle ));
while (!handle); /* avoid handle 0 */ while (!handle); /* avoid handle 0 */
query->func = func;
query->hWnd = hWnd; query->hWnd = hWnd;
query->uMsg = uMsg; query->uMsg = uMsg;
query->handle = UlongToHandle( handle ); query->handle = UlongToHandle( handle );
query->sbuf = sbuf; query->sbuf = sbuf;
query->sbuflen = sbuflen; query->sbuflen = sbuflen;
thread = CreateThread( NULL, 0, func, query, 0, NULL ); if (!TrySubmitThreadpoolCallback( async_worker, query, NULL ))
if (!thread)
{ {
SetLastError( WSAEWOULDBLOCK ); SetLastError( WSAEWOULDBLOCK );
HeapFree( GetProcessHeap(), 0, query ); HeapFree( GetProcessHeap(), 0, query );
return 0; return 0;
} }
CloseHandle( thread );
return UlongToHandle( handle ); return UlongToHandle( handle );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment