From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/msvcrt/concurrency.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcrt/concurrency.c b/dlls/msvcrt/concurrency.c index f8abdff9f5d..8c69c62fa3e 100644 --- a/dlls/msvcrt/concurrency.c +++ b/dlls/msvcrt/concurrency.c @@ -91,12 +91,14 @@ struct scheduler_list {
typedef struct { Context context; + LONG ref; struct scheduler_list scheduler; unsigned int id; union allocator_cache_entry *allocator_cache[8]; } ExternalContextBase; extern const vtable_ptr ExternalContextBase_vtable; static void ExternalContextBase_ctor(ExternalContextBase*); +static void ExternalContextBase_dtor(ExternalContextBase*);
typedef struct Scheduler { const vtable_ptr *vtable; @@ -890,6 +892,7 @@ static void ExternalContextBase_ctor(ExternalContextBase *this)
memset(this, 0, sizeof(*this)); this->context.vtable = &ExternalContextBase_vtable; + this->ref = 1; this->id = InterlockedIncrement(&context_id);
create_default_scheduler(); @@ -3129,9 +3132,11 @@ void msvcrt_free_concurrency(void)
void msvcrt_free_scheduler_thread(void) { - Context *context = try_get_current_context(); + ExternalContextBase *context = (ExternalContextBase*)try_get_current_context(); if (!context) return; - call_Context_dtor(context, 1); + if (context->context.vtable != &ExternalContextBase_vtable || + InterlockedDecrement(&context->ref) == 0) + call_Context_dtor(context, 1); }
#endif /* _MSVCR_VER >= 100 */