[cairo] Cairo mutex implementation for win32 (was Re: Cairo exports and more)

Hans Breuer hans at breuer.org
Mon Sep 19 13:03:24 PDT 2005


On 08.09.2005 17:32, Carl Worth wrote:
> On Thu, 08 Sep 2005 09:41:06 +0200, Doodle wrote:
> 
>>However, the synchronization objects are not leaked, because they
>>are cleaned up in the DLL unload branch of DllMain().
>>
>>To solve the initialization race, I think the only clean solution
>>is to introduce new cairo_initialize() and cairo_uninitialize()
>>functions,
> 
> 
> Can't you just do mutex creation in the "DLL load branch of DllMain" ?
> 
Sure, patch attached. ChangeLog entry something along the line of:

2005-09-19  Hans Breuer  <hans at breuer.org>

	* src/cairoint.c : win32 specific definitions for CAIRO_MUTEX_DECLARE,
	CAIRO_MUTEX_LOCK etc. [not based on win32 mutex but critical sections]
	* src/cairo-win32-surface.c : add DllMain() to do global, single-threaded
	'mutex' (de)initialization. No ifdefs needed, some variables would simply
	not be used when the respective backend would not be compiled in.

Regards,
	Hans

-------- Hans "at" Breuer "dot" Org -----------
Tell me what you need, and I'll tell you how to
get along without it.                -- Dilbert
-------------- next part --------------
diff --exclude-from=c:\util\tool\diff.ign -u --recursive from-cvs/cairo/cairo/src/cairo-win32-surface.c my-gtk/cairo/cairo/src/cairo-win32-surface.c
--- from-cvs/cairo/cairo/src/cairo-win32-surface.c	Fri Aug 26 16:23:09 2005
+++ my-gtk/cairo/cairo/src/cairo-win32-surface.c	Sat Sep 17 16:05:28 2005
@@ -1051,3 +1051,37 @@
     _cairo_win32_surface_flush,
     NULL  /* mark_dirty_rectangle */
 };
+
+/*
+ * Without pthread, on win32 we need to initialize all the 'mutex'es
+ * before use. It is guaranteed that DllMain will get called single
+ * threaded before any other function.
+ * Initializing more than finally needed should not matter much.
+ */
+#ifndef HAVE_PTHREAD_H
+CRITICAL_SECTION cairo_toy_font_face_hash_table_mutex;
+CRITICAL_SECTION cairo_scaled_font_map_mutex;
+CRITICAL_SECTION cairo_ft_unscaled_font_map_mutex;
+
+BOOL WINAPI
+DllMain (HINSTANCE hinstDLL,
+	 DWORD     fdwReason,
+	 LPVOID    lpvReserved)
+{
+  switch (fdwReason)
+  {
+  case DLL_PROCESS_ATTACH:
+    /* every 'mutex' from CAIRO_MUTEX_DECALRE needs to be initialized here */
+    InitializeCriticalSection (&cairo_toy_font_face_hash_table_mutex);
+    InitializeCriticalSection (&cairo_scaled_font_map_mutex);
+    InitializeCriticalSection (&cairo_ft_unscaled_font_map_mutex);
+    break;
+  case DLL_PROCESS_DETACH:
+    DeleteCriticalSection (&cairo_toy_font_face_hash_table_mutex);
+    DeleteCriticalSection (&cairo_scaled_font_map_mutex);
+    DeleteCriticalSection (&cairo_ft_unscaled_font_map_mutex);
+    break;
+  }
+  return TRUE;
+}
+#endif
diff --exclude-from=c:\util\tool\diff.ign -u --recursive from-cvs/cairo/cairo/src/cairoint.h my-gtk/cairo/cairo/src/cairoint.h
--- from-cvs/cairo/cairo/src/cairoint.h	Thu Sep 08 08:10:12 2005
+++ my-gtk/cairo/cairo/src/cairoint.h	Sat Sep 17 00:02:40 2005
@@ -138,6 +138,16 @@
 # define CAIRO_MUTEX_UNLOCK(name) pthread_mutex_unlock (&name)
 #endif
 
+#if !defined(CAIRO_MUTEX_DECLARE) && defined CAIRO_HAS_WIN32_SURFACE
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+  /* the real initialization must take place in DllMain */
+# define CAIRO_MUTEX_DECLARE(name) extern CRITICAL_SECTION name; 
+# define CAIRO_MUTEX_DECLARE_GLOBAL(name) extern LPCRITICAL_SECTION name;
+# define CAIRO_MUTEX_LOCK(name) EnterCriticalSection (&name)
+# define CAIRO_MUTEX_UNLOCK(name) LeaveCriticalSection (&name)
+#endif
+
 #ifndef CAIRO_MUTEX_DECLARE
 # error "No mutex declarations. Cairo will not work with multiple threads." \
 	"(Remove this #error directive to acknowledge & accept this limitation)."


More information about the cairo mailing list