diff --git a/src/win32/cairo-dwrite-font.cpp b/src/win32/cairo-dwrite-font.cpp index 480512000..3f2b455f0 100644 --- a/src/win32/cairo-dwrite-font.cpp +++ b/src/win32/cairo-dwrite-font.cpp @@ -2437,3 +2437,9 @@ _cairo_dwrite_scaled_font_create_win32_scaled_font (cairo_scaled_font_t *scaled_ *new_font = font; return CAIRO_INT_STATUS_SUCCESS; } + +void +cairo_win32_dwrite_finalize () +{ + DWriteFactory::Finalize(); +} diff --git a/src/win32/cairo-dwrite-private.hpp b/src/win32/cairo-dwrite-private.hpp index c2c06d2c1..5e1168cd1 100644 --- a/src/win32/cairo-dwrite-private.hpp +++ b/src/win32/cairo-dwrite-private.hpp @@ -121,6 +121,24 @@ public: return family; } + static void Finalize() + { + /* Loader-lock-safe */ + + if (_cairo_atomic_init_once_check (&mOnceSystemCollection)) { + cairo_win32_async_com_release (mSystemCollection.forget().drop()); + } + + if (_cairo_atomic_init_once_check (&mOnceFactories)) { + cairo_win32_async_com_release (mFactoryInstance.forget().drop()); + cairo_win32_async_com_release (mFactoryInstance1.forget().drop()); + cairo_win32_async_com_release (mFactoryInstance2.forget().drop()); + cairo_win32_async_com_release (mFactoryInstance3.forget().drop()); + cairo_win32_async_com_release (mFactoryInstance4.forget().drop()); + cairo_win32_async_com_release (mFactoryInstance8.forget().drop()); + } + } + private: static void InitializeFactories() { diff --git a/src/win32/cairo-win32-private.h b/src/win32/cairo-win32-private.h index 410a95aa8..25662ef48 100644 --- a/src/win32/cairo-win32-private.h +++ b/src/win32/cairo-win32-private.h @@ -45,6 +45,7 @@ #include "cairo-win32.h" #include +#include #define WIN32_FONT_LOGICAL_SCALE 32 @@ -243,6 +244,9 @@ typedef DWORD (__stdcall *stdcall_free_func_t) (void *); void cairo_win32_async_stdcall_free (stdcall_free_func_t func, void *data); +void +cairo_win32_async_com_release (IUnknown *iface_ptr); + typedef struct { HDC hdc; cairo_bool_t free_hdc; @@ -277,6 +281,9 @@ cairo_int_status_t _cairo_dwrite_scaled_font_create_win32_scaled_font (cairo_scaled_font_t *scaled_font, cairo_scaled_font_t **new_font); +void +cairo_win32_dwrite_finalize (void); + #endif /* CAIRO_HAS_DWRITE_FONT */ CAIRO_END_DECLS diff --git a/src/win32/cairo-win32-system.c b/src/win32/cairo-win32-system.c index ce7ece96f..9397b5a9f 100644 --- a/src/win32/cairo-win32-system.c +++ b/src/win32/cairo-win32-system.c @@ -115,6 +115,15 @@ cairo_win32_async_stdcall_free (stdcall_free_func_t func, void *data) QueueUserWorkItem (func, data, WT_EXECUTEDEFAULT); } +void +cairo_win32_async_com_release (IUnknown *iface_ptr) +{ + if (iface_ptr) { + QueueUserWorkItem ((void *) iface_ptr->lpVtbl->Release, + iface_ptr, WT_EXECUTEDEFAULT); + } +} + static void cairo_win32_initialize (void) { @@ -125,6 +134,8 @@ cairo_win32_initialize (void) static void cairo_win32_finalize (void) { + cairo_win32_dwrite_finalize (); + cairo_win32_thread_data_finalize (); CAIRO_MUTEX_FINALIZE (); }