Rémi Bernon (@rbernon) commented about server/async.c:
+{ + struct async_cancel *cancel = (struct async_cancel *)obj; + + assert( obj->ops == &async_cancel_ops ); + list_remove( &cancel->async_cancels_entry ); + if (cancel->thread) release_object( cancel->thread ); + release_object( cancel->process ); +} + +static struct async_cancel *create_async_cancel( struct process *process, struct thread *thread ) +{ + struct async_cancel *cancel; + + if (!(cancel = alloc_object( &async_cancel_ops ))) return NULL; + cancel->process = (struct process *)grab_object( process ); + cancel->thread = thread ? (struct thread *)grab_object( thread ) : 0; Seems a bit weird to me that a cancel group should need to own a reference to its process/thread, it should never outlive them in the first place. Does it even need pointers to process/thread? It doesn't looks like it in this commit at least.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/7797#note_111819