[2/2] ws2_32: Do not spawn a separate thread for each async task.
Sebastian Lackner
sebastian at fds-team.de
Sun Aug 21 12:55:43 CDT 2016
Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
---
This is unrelated to my recent threadpool patches, but might be a nice improvement
to avoid spawning too many threads.
dlls/ws2_32/async.c | 61 ++++++++++++++++++++++++++--------------------------
1 file changed, 31 insertions(+), 30 deletions(-)
diff --git a/dlls/ws2_32/async.c b/dlls/ws2_32/async.c
index 573349f..56c60fc 100644
--- a/dlls/ws2_32/async.c
+++ b/dlls/ws2_32/async.c
@@ -52,6 +52,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(winsock);
struct async_query_header
{
+ LPARAM (*func)( struct async_query_header *query );
HWND hWnd;
UINT uMsg;
void *sbuf;
@@ -128,13 +129,6 @@ static int list_dup(char** l_src, char* ref, int item_size)
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 */
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 );
}
-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 );
- 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 );
- return finish_query( &aq->query, copy_he( aq->query.sbuf, aq->query.sbuflen, he ));
+ return copy_he( query->sbuf, query->sbuflen, he );
}
/* ----- protoent */
@@ -200,20 +194,20 @@ static LPARAM copy_pe(void *base, int size, const struct WS_protoent* pe)
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 );
- 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 );
- return finish_query( &aq->query, copy_pe( aq->query.sbuf, aq->query.sbuflen, pe ));
+ return copy_pe( query->sbuf, query->sbuflen, pe );
}
/* ----- servent */
@@ -240,20 +234,29 @@ static LPARAM copy_se(void *base, int size, const struct WS_servent* se)
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 );
- 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 );
- 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)
* with no thread support. This relies on the fact that PostMessage() does
* 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 )
{
static LONG next_handle = 0xdead;
- HANDLE thread;
ULONG handle;
do
handle = LOWORD( InterlockedIncrement( &next_handle ));
while (!handle); /* avoid handle 0 */
+ query->func = func;
query->hWnd = hWnd;
query->uMsg = uMsg;
query->handle = UlongToHandle( handle );
query->sbuf = sbuf;
query->sbuflen = sbuflen;
- thread = CreateThread( NULL, 0, func, query, 0, NULL );
- if (!thread)
+ if (!TrySubmitThreadpoolCallback( async_worker, query, NULL ))
{
SetLastError( WSAEWOULDBLOCK );
HeapFree( GetProcessHeap(), 0, query );
return 0;
}
- CloseHandle( thread );
return UlongToHandle( handle );
}
--
2.9.0
More information about the wine-patches
mailing list