Initialize mutexes at central location.

All mutex declarations have been moved to cairo-mutex-list.h.
This should avoid breaking of less frequently tested backends,
when mutexes are introduced or when existing mutexes are renamed.

Instead of initializing mutexes on library startup, mutexes are
lazily initialized within the few entry points of now by calling
CAIRO_MUTEX_INITIALIZE(). Currently only the OS/2 backend takes
care about releasing global mutexes. Therefore there is no counter
part of that macro for finalizing all global mutexes yet - but
as cairo-backend-os2.c shows such a function would be quite
easy to implement.
This commit is contained in:
Mathias Hasselmann 2007-03-20 10:11:14 +01:00
parent aba2b299db
commit be52178443
16 changed files with 258 additions and 190 deletions

View file

@ -187,6 +187,7 @@ libcairo_la_SOURCES = \
cairo-image-surface.c \
cairo-lzw.c \
cairo-matrix.c \
cairo-mutex.c \
cairo-operator.c \
cairo-path.c \
cairo-path-private.h \

View file

@ -39,6 +39,7 @@
*/
#include "cairoint.h"
#include "cairo-mutex-private.h"
/* Forward declare so we can use it as an arbitrary backend for
* _cairo_font_face_nil.
@ -59,6 +60,8 @@ void
_cairo_font_face_init (cairo_font_face_t *font_face,
const cairo_font_face_backend_t *backend)
{
CAIRO_MUTEX_INITIALIZE ();
font_face->status = CAIRO_STATUS_SUCCESS;
font_face->ref_count = 1;
font_face->backend = backend;
@ -66,10 +69,6 @@ _cairo_font_face_init (cairo_font_face_t *font_face,
_cairo_user_data_array_init (&font_face->user_data);
}
/* This mutex protects both cairo_toy_font_hash_table as well as
reference count manipulations for all cairo_font_face_t. */
CAIRO_MUTEX_DECLARE (_cairo_font_face_mutex);
/**
* cairo_font_face_reference:
* @font_face: a #cairo_font_face_t, (may be %NULL in which case this

View file

@ -40,6 +40,7 @@
#include <float.h>
#include "cairo-ft-private.h"
#include "cairo-mutex-private.h"
#include <fontconfig/fontconfig.h>
#include <fontconfig/fcfreetype.h>
@ -150,8 +151,6 @@ typedef struct _cairo_ft_unscaled_font_map {
static cairo_ft_unscaled_font_map_t *cairo_ft_unscaled_font_map = NULL;
CAIRO_MUTEX_DECLARE(_cairo_ft_unscaled_font_map_mutex);
static void
_font_map_release_face_lock_held (cairo_ft_unscaled_font_map_t *font_map,
cairo_ft_unscaled_font_t *unscaled)

52
src/cairo-mutex-list.h Normal file
View file

@ -0,0 +1,52 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2007 Mathias Hasselmann
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* Contributor(s):
* Mathias Hasselmann <mathias.hasselmann@gmx.de>
*/
#ifndef CAIRO_MUTEX_LIST_H
#define CAIRO_MUTEX_LIST_H
CAIRO_MUTEX_DECLARE (_cairo_font_face_mutex);
CAIRO_MUTEX_DECLARE (_cairo_scaled_font_map_mutex);
#if CAIRO_HAS_FT_FONT
CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex);
#endif
#if CAIRO_HAS_XLIB_SURFACE
CAIRO_MUTEX_DECLARE (_xlib_screen_mutex);
#endif
#if CAIRO_HAS_OS2_SURFACE
CAIRO_MUTEX_DECLARE (_global_image_glyph_cache_mutex);
#endif
#endif

123
src/cairo-mutex-private.h Normal file
View file

@ -0,0 +1,123 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2002 University of Southern California
* Copyright © 2005 Red Hat, Inc.
* Copyright © 2007 Mathias Hasselmann
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Mathias Hasselmann <mathias.hasselmann@gmx.de>
*/
#ifndef CAIRO_MUTEX_PRIVATE_H
#define CAIRO_MUTEX_PRIVATE_H
#include "cairoint.h"
#if HAVE_PTHREAD_H
# define CAIRO_MUTEX_INITIALIZE() /* no-op */
# define CAIRO_MUTEX_LOCK(name) pthread_mutex_lock (&name)
# define CAIRO_MUTEX_UNLOCK(name) pthread_mutex_unlock (&name)
# define CAIRO_MUTEX_INIT(mutex) do { \
pthread_mutex_t tmp_mutex = PTHREAD_MUTEX_INITIALIZER; \
memcpy (mutex, &tmp_mutex, sizeof (tmp_mutex)); \
} while (0)
# define CAIRO_MUTEX_FINI(mutex) pthread_mutex_destroy (mutex)
# define CAIRO_MUTEX_NIL_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#elif defined CAIRO_HAS_WIN32_SURFACE
# define CAIRO_MUTEX_LOCK(name) EnterCriticalSection (&name)
# define CAIRO_MUTEX_UNLOCK(name) LeaveCriticalSection (&name)
# define CAIRO_MUTEX_INIT(mutex) InitializeCriticalSection (mutex)
# define CAIRO_MUTEX_FINI(mutex) DeleteCriticalSection (mutex)
# define CAIRO_MUTEX_NIL_INITIALIZER { NULL, 0, 0, NULL, NULL, 0 }
#elif defined __OS2__
# define CAIRO_MUTEX_LOCK(name) DosRequestMutexSem(name, SEM_INDEFINITE_WAIT)
# define CAIRO_MUTEX_UNLOCK(name) DosReleaseMutexSem(name)
# define CAIRO_MUTEX_INIT(mutex) DosCreateMutexSem (NULL, mutex, 0L, FALSE)
# define CAIRO_MUTEX_FINI(mutex) do { \
if (0 != (mutex)) { \
DosCloseMutexSem (*(mutex)); \
(mutex) = 0; \
} \
} while (0)
# define CAIRO_MUTEX_NIL_INITIALIZER 0
#elif defined CAIRO_HAS_BEOS_SURFACE
cairo_private void _cairo_beos_lock(cairo_mutex_t*);
cairo_private void _cairo_beos_unlock(cairo_mutex_t*);
/* the real initialization takes place in a global constructor */
# define CAIRO_MUTEX_LOCK(name) _cairo_beos_lock (&name)
# define CAIRO_MUTEX_UNLOCK(name) _cairo_beos_unlock (&name)
# error "XXX: Someone who understands BeOS needs to add definitions for" \
" cairo_mutex_t, CAIRO_MUTEX_INIT, and CAIRO_MUTEX_FINI," \
" to cairoint.h"
# define CAIRO_MUTEX_INIT(mutex) ???
# define CAIRO_MUTEX_FINI(mutex) ???
# define CAIRO_MUTEX_NIL_INITIALIZER {}
#else
# define CAIRO_MUTEX_LOCK(name)
# define CAIRO_MUTEX_UNLOCK(name)
#endif
#ifndef CAIRO_MUTEX_DECLARE
#define CAIRO_MUTEX_DECLARE(name) extern cairo_mutex_t name;
#endif
#include "cairo-mutex-list.h"
#undef CAIRO_MUTEX_DECLARE
#undef CAIRO_MUTEX_EXTERNAL
#ifndef CAIRO_MUTEX_INITIALIZE
#define CAIRO_MUTEX_INITIALIZE() do { \
if (!_cairo_mutex_initialized) \
_cairo_mutex_initialize(); \
} while(0)
cairo_private extern cairo_bool_t _cairo_mutex_initialized;
cairo_private void _cairo_mutex_initialize(void);
#endif
#endif

51
src/cairo-mutex.c Normal file
View file

@ -0,0 +1,51 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2007 Mathias Hasselmann
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* Contributor(s):
* Mathias Hasselmann <mathias.hasselmann@gmx.de>
*/
#define CAIRO_MUTEX_DECLARE(name) cairo_mutex_t name = CAIRO_MUTEX_NIL_INITIALIZER;
#include "cairo-mutex-private.h"
#if !HAVE_PTHREAD_H
cairo_bool_t _cairo_mutex_initialized = FALSE;
void _cairo_mutex_initialize (void)
{
if (_cairo_mutex_initialized)
return;
#define CAIRO_MUTEX_DECLARE(mutex) CAIRO_MUTEX_INIT (mutex);
#include "cairo-mutex-list.h"
#undef CAIRO_MUTEX_DECLARE
}
#endif

View file

@ -68,14 +68,6 @@
/* Initialization counter: */
static int cairo_os2_initialization_count = 0;
/* The mutex semaphores Cairo uses all around: */
HMTX _cairo_scaled_font_map_mutex = 0;
HMTX _global_image_glyph_cache_mutex = 0;
HMTX _cairo_font_face_mutex = 0;
#ifdef CAIRO_HAS_FT_FONT
HMTX _cairo_ft_unscaled_font_map_mutex = 0;
#endif
static void inline
DisableFPUException (void)
{
@ -103,18 +95,6 @@ cairo_os2_init (void)
DisableFPUException ();
/* Create the mutex semaphores we'll use! */
/* cairo-font.c: */
DosCreateMutexSem (NULL, &_cairo_scaled_font_map_mutex, 0, FALSE);
DosCreateMutexSem (NULL, &_global_image_glyph_cache_mutex, 0, FALSE);
DosCreateMutexSem (NULL, &_cairo_font_face_mutex, 0, FALSE);
#ifdef CAIRO_HAS_FT_FONT
/* cairo-ft-font.c: */
DosCreateMutexSem (NULL, &_cairo_ft_unscaled_font_map_mutex, 0, FALSE);
#endif
/* Initialize FontConfig */
FcInit ();
}
@ -137,28 +117,9 @@ cairo_os2_fini (void)
_cairo_ft_font_reset_static_data ();
#endif
/* Destroy the mutex semaphores we've created! */
/* cairo-font.c: */
if (_cairo_scaled_font_map_mutex) {
DosCloseMutexSem (_cairo_scaled_font_map_mutex);
_cairo_scaled_font_map_mutex = 0;
}
if (_global_image_glyph_cache_mutex) {
DosCloseMutexSem (_global_image_glyph_cache_mutex);
_global_image_glyph_cache_mutex = 0;
}
if (_cairo_font_face_mutex) {
DosCloseMutexSem (_cairo_font_face_mutex);
_cairo_font_face_mutex = 0;
}
#ifdef CAIRO_HAS_FT_FONT
/* cairo-ft-font.c: */
if (_cairo_ft_unscaled_font_map_mutex) {
DosCloseMutexSem (_cairo_ft_unscaled_font_map_mutex);
_cairo_ft_unscaled_font_map_mutex = 0;
}
#endif
#define CAIRO_MUTEX_DECLARE(name) CAIRO_MUTEX_FINI(name)
#include "cairo-mutext-list.h"
#undef CAIRO_MUTEX_DECLARE
/* Uninitialize FontConfig */
FcFini ();

View file

@ -45,6 +45,7 @@
#include "cairo-paginated-surface-private.h"
#include "cairo-meta-surface-private.h"
#include "cairo-analysis-surface-private.h"
#include "cairo-mutex-private.h"
typedef struct _cairo_paginated_surface {
cairo_surface_t base;

View file

@ -29,6 +29,7 @@
*/
#include "cairoint.h"
#include "cairo-mutex-private.h"
const cairo_solid_pattern_t cairo_pattern_nil = {
{ CAIRO_PATTERN_TYPE_SOLID, /* type */
@ -82,6 +83,8 @@ _cairo_pattern_set_error (cairo_pattern_t *pattern,
static void
_cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type)
{
CAIRO_MUTEX_INITIALIZE ();
pattern->type = type;
pattern->ref_count = 1;
pattern->status = CAIRO_STATUS_SUCCESS;

View file

@ -37,6 +37,7 @@
*/
#include "cairoint.h"
#include "cairo-mutex-private.h"
#include "cairo-scaled-font-test.h"
static cairo_bool_t
@ -185,8 +186,6 @@ typedef struct _cairo_scaled_font_map {
static cairo_scaled_font_map_t *cairo_scaled_font_map = NULL;
CAIRO_MUTEX_DECLARE (_cairo_scaled_font_map_mutex);
static int
_cairo_scaled_font_keys_equal (const void *abstract_key_a, const void *abstract_key_b);

View file

@ -39,6 +39,7 @@
#include "cairoint.h"
#include "cairo-surface-fallback-private.h"
#include "cairo-mutex-private.h"
#include "cairo-clip-private.h"
#define DEFINE_NIL_SURFACE(status, name) \
@ -180,10 +181,10 @@ _cairo_surface_init (cairo_surface_t *surface,
const cairo_surface_backend_t *backend,
cairo_content_t content)
{
CAIRO_MUTEX_INITIALIZE ();
surface->backend = backend;
surface->content = content;
surface->type = backend->type;
surface->ref_count = 1;

View file

@ -239,8 +239,6 @@ _win32_scaled_font_create (LOGFONTW *logfont,
cairo_matrix_t scale;
cairo_status_t status;
_cairo_win32_initialize ();
f = malloc (sizeof(cairo_win32_scaled_font_t));
if (f == NULL)
return NULL;
@ -472,8 +470,6 @@ _cairo_win32_scaled_font_create_toy (cairo_toy_font_face_t *toy_face,
int face_name_len;
cairo_status_t status;
_cairo_win32_initialize ();
status = _cairo_utf8_to_utf16 (toy_face->family, -1,
&face_name, &face_name_len);
if (status)
@ -1510,8 +1506,6 @@ _cairo_win32_font_face_scaled_font_create (void *abstract_face,
{
cairo_win32_font_face_t *font_face = abstract_face;
_cairo_win32_initialize ();
*font = _win32_scaled_font_create (&font_face->logfont,
font_face->hfont,
&font_face->base,
@ -1549,8 +1543,6 @@ cairo_win32_font_face_create_for_logfontw (LOGFONTW *logfont)
{
cairo_win32_font_face_t *font_face;
_cairo_win32_initialize ();
font_face = malloc (sizeof (cairo_win32_font_face_t));
if (!font_face) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -1584,8 +1576,6 @@ cairo_win32_font_face_create_for_hfont (HFONT font)
{
cairo_win32_font_face_t *font_face;
_cairo_win32_initialize ();
font_face = malloc (sizeof (cairo_win32_font_face_t));
if (!font_face) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);

View file

@ -105,7 +105,4 @@ _cairo_win32_print_gdi_error (const char *context);
cairo_bool_t
_cairo_surface_is_win32 (cairo_surface_t *surface);
void
_cairo_win32_initialize (void);
#endif /* CAIRO_WIN32_PRIVATE_H */

View file

@ -327,8 +327,6 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
char *bits;
int rowstride;
_cairo_win32_initialize ();
surface = malloc (sizeof (cairo_win32_surface_t));
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -1635,8 +1633,6 @@ cairo_win32_surface_create (HDC hdc)
int depth;
cairo_format_t format;
_cairo_win32_initialize ();
/* Try to figure out the drawing bounds for the Device context
*/
if (GetClipBox (hdc, &rect) == ERROR) {
@ -1887,67 +1883,6 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = {
NULL /* snapshot */
};
/*
* 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.
*/
#if !defined(HAVE_PTHREAD_H)
CRITICAL_SECTION _cairo_scaled_font_map_mutex;
#ifdef CAIRO_HAS_FT_FONT
CRITICAL_SECTION _cairo_ft_unscaled_font_map_mutex;
#endif
CRITICAL_SECTION _cairo_font_face_mutex;
static int _cairo_win32_initialized = 0;
void
_cairo_win32_initialize (void) {
if (_cairo_win32_initialized)
return;
/* every 'mutex' from CAIRO_MUTEX_DECALRE needs to be initialized here */
InitializeCriticalSection (&_cairo_scaled_font_map_mutex);
#ifdef CAIRO_HAS_FT_FONT
InitializeCriticalSection (&_cairo_ft_unscaled_font_map_mutex);
#endif
InitializeCriticalSection (&_cairo_font_face_mutex);
_cairo_win32_initialized = 1;
}
#if !defined(CAIRO_WIN32_STATIC_BUILD)
BOOL WINAPI
DllMain (HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
_cairo_win32_initialize();
break;
case DLL_PROCESS_DETACH:
DeleteCriticalSection (&_cairo_scaled_font_map_mutex);
#ifdef CAIRO_HAS_FT_FONT
DeleteCriticalSection (&_cairo_ft_unscaled_font_map_mutex);
#endif
DeleteCriticalSection (&_cairo_font_face_mutex);
break;
}
return TRUE;
}
#endif
#else
/* Need a function definition here too since it's called outside of ifdefs */
void
_cairo_win32_initialize (void)
{
}
#endif
/* Notes:
*
* Win32 alpha-understanding functions

View file

@ -55,6 +55,7 @@
#include <string.h>
#include "cairo-xlib-private.h"
#include "cairo-mutex-private.h"
#include <fontconfig/fontconfig.h>
@ -243,8 +244,6 @@ _cairo_xlib_init_screen_font_options (cairo_xlib_screen_info_t *info)
cairo_font_options_set_subpixel_order (&info->font_options, subpixel_order);
}
CAIRO_MUTEX_DECLARE(_xlib_screen_mutex);
static cairo_xlib_screen_info_t *_cairo_xlib_screen_list = NULL;
static int

View file

@ -136,81 +136,38 @@ CAIRO_BEGIN_DECLS
#if HAVE_PTHREAD_H
# include <pthread.h>
# define CAIRO_MUTEX_DECLARE(name) static pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER
# define CAIRO_MUTEX_DECLARE_GLOBAL(name) pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER
# define CAIRO_MUTEX_LOCK(name) pthread_mutex_lock (&name)
# define CAIRO_MUTEX_UNLOCK(name) pthread_mutex_unlock (&name)
typedef pthread_mutex_t cairo_mutex_t;
#define CAIRO_MUTEX_INIT(mutex) do { \
pthread_mutex_t tmp_mutex = PTHREAD_MUTEX_INITIALIZER; \
memcpy (mutex, &tmp_mutex, sizeof (tmp_mutex)); \
} while (0)
# define CAIRO_MUTEX_FINI(mutex) pthread_mutex_destroy (mutex)
# define CAIRO_MUTEX_NIL_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#endif
#if !defined(CAIRO_MUTEX_DECLARE) && defined CAIRO_HAS_WIN32_SURFACE
# define WIN32_LEAN_AND_MEAN
typedef pthread_mutex_t cairo_mutex_t;
#elif defined CAIRO_HAS_WIN32_SURFACE
/* We require Windows 2000 features. Although we don't use them here, things
* should still work if this header file ends up being the one to include
* windows.h into a source file, so: */
# if !defined(WINVER) || (WINVER < 0x0500)
# define WINVER 0x0500
# endif
# if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
# define _WIN32_WINNT 0x0500
# endif
# 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)
typedef CRITICAL_SECTION cairo_mutex_t;
# define CAIRO_MUTEX_INIT(mutex) InitializeCriticalSection (mutex)
# define CAIRO_MUTEX_FINI(mutex) DeleteCriticalSection (mutex)
# define CAIRO_MUTEX_NIL_INITIALIZER { 0 }
#endif
#if defined(__OS2__) && !defined(CAIRO_MUTEX_DECLARE)
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
typedef CRITICAL_SECTION cairo_mutex_t;
#elif defined CAIRO_HAS_OS2_SURFACE
# define INCL_BASE
# define INCL_PM
# include <os2.h>
# define CAIRO_MUTEX_DECLARE(name) extern HMTX name
# define CAIRO_MUTEX_DECLARE_GLOBAL(name) extern HMTX name
# define CAIRO_MUTEX_LOCK(name) DosRequestMutexSem(name, SEM_INDEFINITE_WAIT)
# define CAIRO_MUTEX_UNLOCK(name) DosReleaseMutexSem(name)
typedef HMTX cairo_mutex_t;
# define CAIRO_MUTEX_INIT(mutex) DosCreateMutexSem (NULL, mutex, 0L, FALSE)
# define CAIRO_MUTEX_FINI(mutex) DosCloseMutexSem (*(mutex))
# define CAIRO_MUTEX_NIL_INITIALIZER 0
#endif
typedef HMTX cairo_mutex_t;
#if !defined(CAIRO_MUTEX_DECLARE) && defined CAIRO_HAS_BEOS_SURFACE
cairo_private void _cairo_beos_lock(void*);
cairo_private void _cairo_beos_unlock(void*);
/* the real initialization takes place in a global constructor */
# define CAIRO_MUTEX_DECLARE(name) extern void* name;
# define CAIRO_MUTEX_DECLARE_GLOBAL(name) extern void* name;
# define CAIRO_MUTEX_LOCK(name) _cairo_beos_lock (&name)
# define CAIRO_MUTEX_UNLOCK(name) _cairo_beos_unlock (&name)
# error "XXX: Someone who understands BeOS needs to add definitions for" \
" cairo_mutex_t, CAIRO_MUTEX_INIT, and CAIRO_MUTEX_FINI," \
" to cairoint.h"
typedef ??? cairo_mutex_t;
# define CAIRO_MUTEX_INIT(mutex) ???
# define CAIRO_MUTEX_FINI(mutex) ???
# define CAIRO_MUTEX_NIL_INITIALIZER {}
#endif
#elif defined CAIRO_HAS_BEOS_SURFACE
typedef void* cairo_mutex_t;
#ifndef CAIRO_MUTEX_DECLARE
# error "No mutex declarations. Cairo will not work with multiple threads." \
"(Remove this #error directive to acknowledge & accept this limitation)."
# define CAIRO_MUTEX_DECLARE(name)
# define CAIRO_MUTEX_DECLARE_GLOBAL(name)
# define CAIRO_MUTEX_LOCK(name)
# define CAIRO_MUTEX_UNLOCK(name)
#endif
#undef MIN