Bug 4692

Summary: _global_image_glyph_cache_mutex is not initialized in win32 + static builds
Product: cairo Reporter: Adam Strzelecki <ono>
Component: win32 backendAssignee: Owen Taylor <otaylor>
Status: RESOLVED FIXED QA Contact: cairo-bugs mailing list <cairo-bugs>
Severity: critical    
Priority: high CC: chris
Version: 1.0.2   
Hardware: x86 (IA32)   
OS: Windows (All)   
Whiteboard:
i915 platform: i915 features:

Description Adam Strzelecki 2005-10-05 06:38:40 UTC
Uninitialized _global_image_glyph_cache_mutex at win32 platform causes access
violation at cairo-font.c.

Moreover since Win32 mutex needs to be initialized prior using all of them are
initialized in DllMain() which does the job well on shared library system but
not on static build.

I propose 2 functions
cairo_win32_init()
cairo_win32_release()

That should be called in win32 static build to initialize mutex variables.

Please use following code snippet from cairo-win32-surface.c:

---
/*
 * 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
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 */
    cairo_win32_init ();
    break;
  case DLL_PROCESS_DETACH:
    cairo_win32_release ();
    break;
  }
  return TRUE;
}

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 _global_image_glyph_cache_mutex;

void
cairo_win32_init ()
{
  /* 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);
  InitializeCriticalSection (&_global_image_glyph_cache_mutex);
}

void
cairo_win32_release ()
{
  DeleteCriticalSection (&cairo_toy_font_face_hash_table_mutex);
  DeleteCriticalSection (&cairo_scaled_font_map_mutex);
  DeleteCriticalSection (&cairo_ft_unscaled_font_map_mutex);
  DeleteCriticalSection (&_global_image_glyph_cache_mutex);
}
#endif
---

Regards,
Adam Strzelecki
Comment 1 Simon Urbanek 2005-12-19 06:08:42 UTC
Confirmed (w32 cross-compile)
Fix:

--- cairo-win32-surface.c~      2005-10-03 16:44:43.000000000 -0400
+++ cairo-win32-surface.c       2005-12-18 13:58:21.000000000 -0500
@@ -1062,6 +1062,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 _global_image_glyph_cache_mutex;
 
 BOOL WINAPI
 DllMain (HINSTANCE hinstDLL,
@@ -1072,11 +1073,13 @@
   {
   case DLL_PROCESS_ATTACH:
     /* every 'mutex' from CAIRO_MUTEX_DECALRE needs to be initialized here */
+    InitializeCriticalSection (&_global_image_glyph_cache_mutex);
     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 (&_global_image_glyph_cache_mutex);
     DeleteCriticalSection (&cairo_toy_font_face_hash_table_mutex);
     DeleteCriticalSection (&cairo_scaled_font_map_mutex);
     DeleteCriticalSection (&cairo_ft_unscaled_font_map_mutex);
Comment 2 Behdad Esfahbod 2006-06-29 08:33:51 UTC
Discussing this with cworth, we think what we need is a cairo_win32_init() that
should be called before any multi-thread stuff.  And given that, better to
remove the dll initialization stuff, such that everyone is forced to actually
call the win32_init() on win32.
Comment 3 Chris Wilson 2008-01-11 06:55:52 UTC
Cairo's mutex handling and initialization was cleaned up by Behdad during Apr/May 2007 (and included similar fixes).

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.