winhttp: Use default thread pool.

Signed-off-by: Paul Gofman <pgofman@codeweavers.com>
Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Paul Gofman 2022-03-15 19:07:25 +03:00 committed by Alexandre Julliard
parent 88334e1c18
commit 482a8b7de7
3 changed files with 64 additions and 30 deletions

View File

@ -122,54 +122,82 @@ static const WCHAR *attribute_table[] =
NULL /* WINHTTP_QUERY_PASSPORT_CONFIG = 78 */
};
static DWORD start_queue( struct queue *queue )
void init_queue( struct queue *queue )
{
if (queue->pool) return ERROR_SUCCESS;
if (!(queue->pool = CreateThreadpool( NULL ))) return GetLastError();
SetThreadpoolThreadMinimum( queue->pool, 1 );
SetThreadpoolThreadMaximum( queue->pool, 1 );
memset( &queue->env, 0, sizeof(queue->env) );
queue->env.Version = 1;
queue->env.Pool = queue->pool;
TRACE("started %p\n", queue);
return ERROR_SUCCESS;
InitializeSRWLock( &queue->lock );
list_init( &queue->queued_tasks );
queue->callback_running = FALSE;
}
void stop_queue( struct queue *queue )
{
if (!queue->pool) return;
CloseThreadpool( queue->pool );
queue->pool = NULL;
assert( list_empty( &queue->queued_tasks ));
TRACE("stopped %p\n", queue);
}
static void CALLBACK task_callback( TP_CALLBACK_INSTANCE *instance, void *ctx, TP_WORK *work )
static struct task_header *get_next_task( struct queue *queue )
{
struct task_header *task_hdr = ctx;
struct list *entry;
task_hdr->callback( task_hdr );
release_object( task_hdr->obj );
free( task_hdr );
AcquireSRWLockExclusive( &queue->lock );
assert( queue->callback_running );
if ((entry = list_head( &queue->queued_tasks )))
list_remove( entry );
else
queue->callback_running = FALSE;
ReleaseSRWLockExclusive( &queue->lock );
if (!entry) return NULL;
return LIST_ENTRY( entry, struct task_header, entry );
}
static void CALLBACK task_callback( TP_CALLBACK_INSTANCE *instance, void *ctx )
{
struct task_header *task, *next_task;
struct queue *queue = ctx;
TRACE( "instance %p.\n", instance );
task = get_next_task( queue );
while (task)
{
task->callback( task );
/* Queue object may be freed by release_object() unless there is another task referencing it. */
next_task = get_next_task( queue );
release_object( task->obj );
free( task );
task = next_task;
}
TRACE( "instance %p exiting.\n", instance );
}
static DWORD queue_task( struct queue *queue, TASK_CALLBACK task, struct task_header *task_hdr,
struct object_header *obj )
{
TP_WORK *work;
DWORD ret;
BOOL callback_running;
if ((ret = start_queue( queue ))) return ret;
if (!(work = CreateThreadpoolWork( task_callback, task_hdr, &queue->env ))) return GetLastError();
TRACE("queueing %p in %p\n", task_hdr, queue);
task_hdr->callback = task;
task_hdr->obj = obj;
addref_object( obj );
SubmitThreadpoolWork( work );
CloseThreadpoolWork( work );
AcquireSRWLockExclusive( &queue->lock );
list_add_tail( &queue->queued_tasks, &task_hdr->entry );
if (!(callback_running = queue->callback_running))
{
if ((queue->callback_running = TrySubmitThreadpoolCallback( task_callback, queue, NULL )))
callback_running = TRUE;
else
list_remove( &task_hdr->entry );
}
ReleaseSRWLockExclusive( &queue->lock );
if (!callback_running)
{
release_object( obj );
free( task_hdr );
ERR( "Submiting threadpool callback failed, err %lu.\n", GetLastError() );
return ERROR_OUTOFMEMORY;
}
return ERROR_SUCCESS;
}
@ -3096,6 +3124,8 @@ HINTERNET WINAPI WinHttpWebSocketCompleteUpgrade( HINTERNET hrequest, DWORD_PTR
socket->hdr.notify_mask = request->hdr.notify_mask;
socket->hdr.context = context;
InitializeSRWLock( &socket->send_lock );
init_queue( &socket->send_q );
init_queue( &socket->recv_q );
addref_object( &request->hdr );
socket->request = request;

View File

@ -1160,6 +1160,7 @@ HINTERNET WINAPI WinHttpOpenRequest( HINTERNET hconnect, const WCHAR *verb, cons
request->hdr.notify_mask = connect->hdr.notify_mask;
request->hdr.context = connect->hdr.context;
request->hdr.redirect_policy = connect->hdr.redirect_policy;
init_queue( &request->queue );
addref_object( &connect->hdr );
request->connect = connect;

View File

@ -159,8 +159,9 @@ struct authinfo
struct queue
{
TP_POOL *pool;
TP_CALLBACK_ENVIRON env;
SRWLOCK lock;
struct list queued_tasks;
BOOL callback_running;
};
enum request_flags
@ -277,6 +278,7 @@ typedef void (*TASK_CALLBACK)( void *ctx );
struct task_header
{
struct list entry;
TASK_CALLBACK callback;
struct object_header *obj;
};
@ -355,6 +357,7 @@ BOOL free_handle( HINTERNET ) DECLSPEC_HIDDEN;
void send_callback( struct object_header *, DWORD, LPVOID, DWORD ) DECLSPEC_HIDDEN;
void close_connection( struct request * ) DECLSPEC_HIDDEN;
void init_queue( struct queue *queue ) DECLSPEC_HIDDEN;
void stop_queue( struct queue * ) DECLSPEC_HIDDEN;
void netconn_close( struct netconn * ) DECLSPEC_HIDDEN;