Module: wine Branch: master Commit: a5d569934ff347ca183dbc03c11ca2837cb911c3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=a5d569934ff347ca183dbc03c1...
Author: Vincent Povirk vincent@codeweavers.com Date: Thu Nov 6 11:37:46 2014 -0600
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;