diff options
author | Marti <marti.maria@tktbrainpower.com> | 2016-08-23 18:23:44 +0200 |
---|---|---|
committer | Marti <marti.maria@tktbrainpower.com> | 2016-08-23 18:23:44 +0200 |
commit | 00e2a0c6a25b366bb28efee228fa40572279eb27 (patch) | |
tree | 3109bbbb814427dd82093e6f40d49bb0e015487b /src/lcms2_internal.h | |
parent | e990004a6cb76685b53cb5884db9e0cabfdea30e (diff) | |
download | lcms2-00e2a0c6a25b366bb28efee228fa40572279eb27.tar.gz |
Better critical section initialization
Contributed patch from Robin Watts (Artifex).
Prevents ApplicationVerifer to complain about the static initialization
of critical
section. Applies to windows only.
Diffstat (limited to 'src/lcms2_internal.h')
-rw-r--r-- | src/lcms2_internal.h | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/src/lcms2_internal.h b/src/lcms2_internal.h index 727cb06..75c4893 100644 --- a/src/lcms2_internal.h +++ b/src/lcms2_internal.h @@ -185,6 +185,34 @@ cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d) #include <windows.h> +// The locking scheme in LCMS requires a single 'top level' mutex +// to work. This is actually implemented on Windows as a +// CriticalSection, because they are lighter weight. With +// pthreads, this is statically inited. Unfortunately, windows +// can't officially statically init critical sections. +// +// We can work around this in 2 ways. +// +// 1) We can use a proper mutex purely to protect the init +// of the CriticalSection. This in turns requires us to protect +// the Mutex creation, which we can do using the snappily +// named InterlockedCompareExchangePointer API (present on +// windows XP and above). +// +// 2) In cases where we want to work on pre-Windows XP, we +// can use an even more horrible hack described below. +// +// So why wouldn't we always use 2)? Because not calling +// the init function for a critical section means it fails +// testing with ApplicationVerifier (and presumably similar +// tools). +// +// We therefore default to 1, and people who want to be able +// to run on pre-Windows XP boxes can build with: +// CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT +// defined. This is automatically set for builds using +// versions of MSVC that don't have this API available. +// // From: http://locklessinc.com/articles/pthreads_on_windows/ // The pthreads API has an initialization macro that has no correspondence to anything in // the windows API. By investigating the internal definition of the critical section type, @@ -206,14 +234,30 @@ cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d) typedef CRITICAL_SECTION _cmsMutex; -#define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0} - #ifdef _MSC_VER # if (_MSC_VER >= 1800) # pragma warning(disable : 26135) # endif #endif +#ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT +// If we are building with a version of MSVC smaller +// than 1400 (i.e. before VS2005) then we don't have +// the InterlockedCompareExchangePointer API, so use +// the old version. +# ifdef _MSC_VER +# if _MSC_VER < 1400 +# define CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT +# endif +# endif +#endif + +#ifdef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT +# define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0} +#else +# define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG)NULL,-1,0,0,0,0} +#endif + cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) { EnterCriticalSection(m); |