[cairo] Counting semantics of cairo_ft_scaled_font_lock_face

Jan Slupski jslupski at juljas.net
Mon Feb 12 20:52:40 PST 2007


On Sat, 10 Feb 2007, Carl Worth wrote:

> So, Jan and I have been trying to fix the multi-threaded text locking
> bugs. I've attached below my latest series of patches. It seems to
> eliminate the bugs we've seen so far.

For me it seems that current git code + this series of patches 
fixes all threading issues on my Linux box.


To be able compile on win32 I have had to add minor patch
that adds suitable mutex declarations in win32 code.
(C-jans-01-win32-mutex-define.patch)


But then it turned out there there is one more issue that
makes cairo hiccup in multithread mode in Windows.

Win32 code used to pass single DC to all font related 
functions. It was allocated once in _get_global_font_dc, 
and shared by all threads.

It seems that that kind of DC usage is not multithread safe.
In other hand creating new DC on each call was not an option since
I've been running of of free DCs very fast.

I'm not sure what is the best way to solve it (and what cairo's
coding standards says about globals, and TLS usage), but I have hacked
workaround - to keep one instance of DC for each thread in Thread Local
Storage and it fixed the problem. 
(C-jans-02-win32-hdc-in-tls.patch)

Jan

PS.
I did most of testing with Cairo 1.2.6 code.

    _  _  _  _  _____________________________________________
    | |_| |\ |  S L U P S K I             jslupski at juljas.net
  |_| | | | \|                             http://juljas.net/
-------------- next part --------------
Index: cairo-1.2.6/src/cairo-win32-surface.c
===================================================================
--- cairo-1.2.6/src/cairo-win32-surface.c	(revision 2007)
+++ cairo-1.2.6/src/cairo-win32-surface.c	(working copy)
@@ -1178,6 +1178,7 @@
 CRITICAL_SECTION cairo_toy_font_face_hash_table_mutex;
 CRITICAL_SECTION cairo_scaled_font_map_mutex;
 CRITICAL_SECTION cairo_ft_unscaled_font_map_mutex;
+CRITICAL_SECTION cairo_font_face_mutex;
 
 static int _cairo_win32_initialized = 0;
 
@@ -1190,6 +1191,7 @@
     InitializeCriticalSection (&cairo_toy_font_face_hash_table_mutex);
     InitializeCriticalSection (&cairo_scaled_font_map_mutex);
     InitializeCriticalSection (&cairo_ft_unscaled_font_map_mutex);
+    InitializeCriticalSection (&cairo_font_face_mutex);
 
     _cairo_win32_initialized = 1;
 }
@@ -1209,6 +1211,7 @@
     DeleteCriticalSection (&cairo_toy_font_face_hash_table_mutex);
     DeleteCriticalSection (&cairo_scaled_font_map_mutex);
     DeleteCriticalSection (&cairo_ft_unscaled_font_map_mutex);
+    DeleteCriticalSection (&cairo_font_face_mutex);
     break;
   }
   return TRUE;
-------------- next part --------------
Index: cairo-1.2.6/src/cairo-win32-surface.c
===================================================================
--- cairo-1.2.6/src/cairo-win32-surface.c	(revision 2011)
+++ cairo-1.2.6/src/cairo-win32-surface.c	(revision 2012)
@@ -1181,6 +1181,7 @@
 CRITICAL_SECTION cairo_font_face_mutex;
 
 static int _cairo_win32_initialized = 0;
+DWORD _hdc_tls_index = 0;
 
 void
 _cairo_win32_initialize () {
@@ -1193,6 +1194,10 @@
     InitializeCriticalSection (&cairo_ft_unscaled_font_map_mutex);
     InitializeCriticalSection (&cairo_font_face_mutex);
 
+    _hdc_tls_index = TlsAlloc(); 
+		if(_hdc_tls_index == TLS_OUT_OF_INDEXES) /* This call can fail. What to do? */
+			_cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     _cairo_win32_initialized = 1;
 }
 
Index: cairo-1.2.6/src/cairo-win32-private.h
===================================================================
--- cairo-1.2.6/src/cairo-win32-private.h	(revision 2011)
+++ cairo-1.2.6/src/cairo-win32-private.h	(revision 2012)
@@ -82,6 +82,8 @@
 cairo_bool_t
 _cairo_surface_is_win32 (cairo_surface_t *surface);
 
+extern DWORD _hdc_tls_index;
+
 void
 _cairo_win32_initialize ();
 
Index: cairo-1.2.6/src/cairo-win32-font.c
===================================================================
--- cairo-1.2.6/src/cairo-win32-font.c	(revision 2011)
+++ cairo-1.2.6/src/cairo-win32-font.c	(revision 2012)
@@ -328,7 +328,7 @@
 static HDC
 _get_global_font_dc (void)
 {
-    static HDC hdc;
+    HDC hdc=TlsGetValue(_hdc_tls_index);
 
     if (!hdc) {
 	hdc = CreateCompatibleDC (NULL);
@@ -342,6 +342,8 @@
 	    DeleteDC (hdc);
 	    return NULL;
 	}
+
+	TlsSetValue(_hdc_tls_index, hdc);
     }
 
     return hdc;


More information about the cairo mailing list