summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarti Maria <marti.maria@littlecms.com>2022-01-06 17:56:47 +0100
committerMarti Maria <marti.maria@littlecms.com>2022-01-06 17:56:47 +0100
commit0728390fb452d26c445546a912c634f186d58381 (patch)
tree57a4d99ff95415be1fd03b3e3b113685ffb2de89
parentd538d163dbef7a175b1ec46b67375d73e38dc62d (diff)
downloadlcms2-0728390fb452d26c445546a912c634f186d58381.tar.gz
Make sure context mutex critical section is initialized
AppVerifier complains in some cases if the critical section is not initialized. Should address #289
-rw-r--r--src/cmsplugin.c83
1 files changed, 57 insertions, 26 deletions
diff --git a/src/cmsplugin.c b/src/cmsplugin.c
index 5aca69a..8c9e4c8 100644
--- a/src/cmsplugin.c
+++ b/src/cmsplugin.c
@@ -671,17 +671,65 @@ static struct _cmsContext_struct globalContext = {
static _cmsMutex _cmsContextPoolHeadMutex = CMS_MUTEX_INITIALIZER;
static struct _cmsContext_struct* _cmsContextPoolHead = NULL;
+
+// Make sure context is initialized (needed on windows)
+static
+cmsBool InitContextMutex(void)
+{
+ // See the comments regarding locking in lcms2_internal.h
+ // for an explanation of why we need the following code.
+#ifndef CMS_NO_PTHREADS
+#ifdef CMS_IS_WINDOWS_
+#ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
+
+ static cmsBool already_initialized = FALSE;
+
+ if (!already_initialized)
+ {
+ static HANDLE _cmsWindowsInitMutex = NULL;
+ static volatile HANDLE* mutex = &_cmsWindowsInitMutex;
+
+ if (*mutex == NULL)
+ {
+ HANDLE p = CreateMutex(NULL, FALSE, NULL);
+ if (p && InterlockedCompareExchangePointer((void**)mutex, (void*)p, NULL) != NULL)
+ CloseHandle(p);
+ }
+ if (*mutex == NULL || WaitForSingleObject(*mutex, INFINITE) == WAIT_FAILED)
+ {
+ cmsSignalError(0, cmsERROR_INTERNAL, "Mutex lock failed");
+ return FALSE;
+ }
+ if (((void**)&_cmsContextPoolHeadMutex)[0] == NULL)
+ InitializeCriticalSection(&_cmsContextPoolHeadMutex);
+ if (*mutex == NULL || !ReleaseMutex(*mutex))
+ {
+ cmsSignalError(0, cmsERROR_INTERNAL, "Mutex unlock failed");
+ return FALSE;
+ }
+ already_initialized = TRUE;
+ }
+#endif
+#endif
+#endif
+
+ return TRUE;
+}
+
+
+
// Internal, get associated pointer, with guessing. Never returns NULL.
struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID)
{
struct _cmsContext_struct* id = (struct _cmsContext_struct*) ContextID;
struct _cmsContext_struct* ctx;
-
// On 0, use global settings
if (id == NULL)
return &globalContext;
+ InitContextMutex();
+
// Search
_cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
@@ -784,31 +832,7 @@ cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData)
struct _cmsContext_struct* ctx;
struct _cmsContext_struct fakeContext;
- // See the comments regarding locking in lcms2_internal.h
- // for an explanation of why we need the following code.
-#ifndef CMS_NO_PTHREADS
-#ifdef CMS_IS_WINDOWS_
-#ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
- {
- static HANDLE _cmsWindowsInitMutex = NULL;
- static volatile HANDLE* mutex = &_cmsWindowsInitMutex;
-
- if (*mutex == NULL)
- {
- HANDLE p = CreateMutex(NULL, FALSE, NULL);
- if (p && InterlockedCompareExchangePointer((void **)mutex, (void*)p, NULL) != NULL)
- CloseHandle(p);
- }
- if (*mutex == NULL || WaitForSingleObject(*mutex, INFINITE) == WAIT_FAILED)
- return NULL;
- if (((void **)&_cmsContextPoolHeadMutex)[0] == NULL)
- InitializeCriticalSection(&_cmsContextPoolHeadMutex);
- if (*mutex == NULL || !ReleaseMutex(*mutex))
- return NULL;
- }
-#endif
-#endif
-#endif
+ if (!InitContextMutex()) return NULL;
_cmsInstallAllocFunctions(_cmsFindMemoryPlugin(Plugin), &fakeContext.DefaultMemoryManager);
@@ -884,6 +908,8 @@ cmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData)
if (ctx == NULL)
return NULL; // Something very wrong happened
+ if (!InitContextMutex()) return NULL;
+
// Setup default memory allocators
memcpy(&ctx->DefaultMemoryManager, &src->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager));
@@ -943,6 +969,9 @@ void CMSEXPORT cmsDeleteContext(cmsContext ContextID)
struct _cmsContext_struct fakeContext;
struct _cmsContext_struct* prev;
+
+ InitContextMutex();
+
memcpy(&fakeContext.DefaultMemoryManager, &ctx->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager));
fakeContext.chunks[UserPtr] = ctx ->chunks[UserPtr];
@@ -1004,6 +1033,8 @@ cmsBool _cmsGetTime(struct tm* ptr_time)
#elif defined(HAVE_GMTIME_S)
t = gmtime_s(&tm, &now) == 0 ? &tm : NULL;
#else
+ if (!InitContextMutex()) return FALSE;
+
_cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
t = gmtime(&now);
_cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);