[PATCH v2 2/7] winhttp: Implement reference counting for tasks.
Paul Gofman
wine at gitlab.winehq.org
Tue Jun 7 12:20:53 CDT 2022
From: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
dlls/winhttp/request.c | 32 +++++++++++++++++++++++++++-----
dlls/winhttp/winhttp_private.h | 1 +
2 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c
index 9abe4f45598..70d727c7e2e 100644
--- a/dlls/winhttp/request.c
+++ b/dlls/winhttp/request.c
@@ -135,20 +135,41 @@ void stop_queue( struct queue *queue )
TRACE("stopped %p\n", queue);
}
+static void addref_task( struct task_header *task )
+{
+ InterlockedIncrement( &task->refs );
+}
+
+static void release_task( struct task_header *task )
+{
+ if (!InterlockedDecrement( &task->refs ))
+ free( task );
+}
+
static struct task_header *get_next_task( struct queue *queue, struct task_header *prev_task )
{
+ struct task_header *task;
struct list *entry;
AcquireSRWLockExclusive( &queue->lock );
assert( queue->callback_running );
if (prev_task)
+ {
list_remove( &prev_task->entry );
-
- if (!(entry = list_head( &queue->queued_tasks )))
+ release_task( prev_task );
+ }
+ if ((entry = list_head( &queue->queued_tasks )))
+ {
+ task = LIST_ENTRY( entry, struct task_header, entry );
+ addref_task( task );
+ }
+ else
+ {
+ task = NULL;
queue->callback_running = FALSE;
+ }
ReleaseSRWLockExclusive( &queue->lock );
- if (!entry) return NULL;
- return LIST_ENTRY( entry, struct task_header, entry );
+ return task;
}
static void CALLBACK task_callback( TP_CALLBACK_INSTANCE *instance, void *ctx )
@@ -165,7 +186,7 @@ static void CALLBACK task_callback( TP_CALLBACK_INSTANCE *instance, void *ctx )
/* Queue object may be freed by release_object() unless there is another task referencing it. */
next_task = get_next_task( queue, task );
release_object( task->obj );
- free( task );
+ release_task( task );
task = next_task;
}
TRACE( "instance %p exiting.\n", instance );
@@ -178,6 +199,7 @@ static DWORD queue_task( struct queue *queue, TASK_CALLBACK task, struct task_he
TRACE("queueing %p in %p\n", task_hdr, queue);
task_hdr->callback = task;
+ task_hdr->refs = 1;
task_hdr->obj = obj;
addref_object( obj );
diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h
index 4754d9258d1..ee3cdb78157 100644
--- a/dlls/winhttp/winhttp_private.h
+++ b/dlls/winhttp/winhttp_private.h
@@ -281,6 +281,7 @@ struct task_header
struct list entry;
TASK_CALLBACK callback;
struct object_header *obj;
+ volatile LONG refs;
};
struct send_request
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/195
More information about the wine-devel
mailing list