windowscodecs: Fix race condition loading libpng.

Vincent Povirk madewokherd at gmail.com
Thu Nov 6 11:40:39 CST 2014


-------------- next part --------------
From 715e26aa786028f9b78e00755c4fbb7e801397f9 Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Thu, 6 Nov 2014 11:37:46 -0600
Subject: [PATCH] windowscodecs: Fix race condition loading libpng.

---
 dlls/windowscodecs/pngformat.c | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/dlls/windowscodecs/pngformat.c b/dlls/windowscodecs/pngformat.c
index a8ecb73..b3e6cc6 100644
--- a/dlls/windowscodecs/pngformat.c
+++ b/dlls/windowscodecs/pngformat.c
@@ -200,13 +200,28 @@ MAKE_FUNCPTR(png_write_info);
 MAKE_FUNCPTR(png_write_rows);
 #undef MAKE_FUNCPTR
 
+static CRITICAL_SECTION init_png_cs;
+static CRITICAL_SECTION_DEBUG init_png_cs_debug =
+{
+    0, 0, &init_png_cs,
+    { &init_png_cs_debug.ProcessLocksList,
+      &init_png_cs_debug.ProcessLocksList },
+    0, 0, { (DWORD_PTR)(__FILE__ ": init_png_cs") }
+};
+static CRITICAL_SECTION init_png_cs = { &init_png_cs_debug, -1, 0, 0, 0, 0 };
+
 static void *load_libpng(void)
 {
-    if((libpng_handle = wine_dlopen(SONAME_LIBPNG, RTLD_NOW, NULL, 0)) != NULL) {
+    void *result;
+
+    EnterCriticalSection(&init_png_cs);
+
+    if(!libpng_handle && (libpng_handle = wine_dlopen(SONAME_LIBPNG, RTLD_NOW, NULL, 0)) != NULL) {
 
 #define LOAD_FUNCPTR(f) \
     if((p##f = wine_dlsym(libpng_handle, #f, NULL, 0)) == NULL) { \
         libpng_handle = NULL; \
+        LeaveCriticalSection(&init_png_cs); \
         return NULL; \
     }
         LOAD_FUNCPTR(png_create_read_struct);
@@ -251,7 +266,12 @@ static void *load_libpng(void)
 
 #undef LOAD_FUNCPTR
     }
-    return libpng_handle;
+
+    result = libpng_handle;
+
+    LeaveCriticalSection(&init_png_cs);
+
+    return result;
 }
 
 static void user_error_fn(png_structp png_ptr, png_const_charp error_message)
@@ -997,7 +1017,7 @@ HRESULT PngDecoder_CreateInstance(REFIID iid, void** ppv)
 
     *ppv = NULL;
 
-    if (!libpng_handle && !load_libpng())
+    if (!load_libpng())
     {
         ERR("Failed reading PNG because unable to find %s\n",SONAME_LIBPNG);
         return E_FAIL;
@@ -1726,7 +1746,7 @@ HRESULT PngEncoder_CreateInstance(REFIID iid, void** ppv)
 
     *ppv = NULL;
 
-    if (!libpng_handle && !load_libpng())
+    if (!load_libpng())
     {
         ERR("Failed writing PNG because unable to find %s\n",SONAME_LIBPNG);
         return E_FAIL;
-- 
2.1.0



More information about the wine-patches mailing list