From a0feeef52efde872c6d6e458c8e15616da0bf74f Mon Sep 17 00:00:00 2001
From: Konstantin Ritt <ritt.ks@gmail.com>
Date: Fri, 7 Oct 2011 14:45:40 +0200
Subject: fix possible race conditions

the initialization guard must be set after the initialization is done;
for the code assumed to be only executed in a single thread, this change was done
just for consistency - in order to avoid similar issues by copy-pasting in future

Merge-request: 2655
Reviewed-by: Jan-Arve Saether <jan-arve.saether@nokia.com>
---
 src/activeqt/shared/qaxtypes.cpp             |  4 ++--
 src/corelib/io/qfilesystemengine_win.cpp     |  5 +++--
 src/corelib/kernel/qeventdispatcher_win.cpp  |  3 ++-
 src/gui/accessible/qaccessible_win.cpp       |  2 +-
 src/gui/dialogs/qfiledialog_win.cpp          |  3 ++-
 src/gui/dialogs/qwizard_win.cpp              |  2 +-
 src/gui/image/qpixmap_mac.cpp                |  4 +++-
 src/gui/kernel/qapplication_win.cpp          | 12 ++++++------
 src/gui/kernel/qguifunctions_wince.cpp       |  5 ++---
 src/gui/kernel/qmime_mac.cpp                 |  4 +++-
 src/gui/styles/qwindowsvistastyle.cpp        |  2 +-
 src/gui/styles/qwindowsxpstyle.cpp           |  2 +-
 src/gui/text/qfontengine_win.cpp             |  5 ++++-
 src/gui/widgets/qmenu_wince.cpp              |  2 +-
 src/network/kernel/qnetworkinterface_win.cpp |  4 +---
 15 files changed, 33 insertions(+), 26 deletions(-)

diff --git a/src/activeqt/shared/qaxtypes.cpp b/src/activeqt/shared/qaxtypes.cpp
index 8835caf..9452c6a 100644
--- a/src/activeqt/shared/qaxtypes.cpp
+++ b/src/activeqt/shared/qaxtypes.cpp
@@ -665,9 +665,9 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
             static PGetRecordInfoFromTypeInfo pGetRecordInfoFromTypeInfo = 0;
             static bool resolved = false;
             if (!resolved) {
+                QSystemLibrary oleaut32(QLatin1String("oleaut32"));
+                pGetRecordInfoFromTypeInfo = (PGetRecordInfoFromTypeInfo)oleaut32.resolve("GetRecordInfoFromTypeInfo");
                 resolved = true;
-                pGetRecordInfoFromTypeInfo = (PGetRecordInfoFromTypeInfo)QSystemLibrary::resolve(QLatin1String("oleaut32"),
-                                              "GetRecordInfoFromTypeInfo");
             }
             if (!pGetRecordInfoFromTypeInfo)
                 break;
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 8622121..218cf20 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -186,7 +186,6 @@ static void resolveLibs()
         }
 #endif
 
-        triedResolve = true;
 #if !defined(Q_OS_WINCE)
         QSystemLibrary advapi32(QLatin1String("advapi32"));
         if (advapi32.load()) {
@@ -229,6 +228,7 @@ static void resolveLibs()
         if (kernel32.load())
             ptrGetVolumePathNamesForVolumeNameW = (PtrGetVolumePathNamesForVolumeNameW)kernel32.resolve("GetVolumePathNamesForVolumeNameW");
 #endif
+        triedResolve = true;
     }
 }
 #endif // QT_NO_LIBRARY
@@ -254,7 +254,7 @@ static bool resolveUNCLibs()
             return ptrNetShareEnum && ptrNetApiBufferFree;
         }
 #endif
-        triedResolve = true;
+
 #if !defined(Q_OS_WINCE)
         QSystemLibrary netapi32(QLatin1String("kernel32"));
         if (netapi32.load()) {
@@ -262,6 +262,7 @@ static bool resolveUNCLibs()
             ptrNetApiBufferFree = (PtrNetApiBufferFree)netapi32.resolve("NetApiBufferFree");
         }
 #endif
+        triedResolve = true;
     }
     return ptrNetShareEnum && ptrNetApiBufferFree;
 }
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 3e367b7..365b28e 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -327,7 +327,6 @@ static void resolveTimerAPI()
         if (triedResolve)
             return;
 #endif
-        triedResolve = true;
 #ifndef Q_OS_WINCE
         QSystemLibrary library(QLatin1String("Mmtimer"));
 #else
@@ -337,6 +336,8 @@ static void resolveTimerAPI()
             qtimeSetEvent = (ptimeSetEvent)library.resolve("timeSetEvent");
             qtimeKillEvent = (ptimeKillEvent)library.resolve("timeKillEvent");
         }
+
+        triedResolve = true;
     }
 }
 
diff --git a/src/gui/accessible/qaccessible_win.cpp b/src/gui/accessible/qaccessible_win.cpp
index 1fd1bfd..c1bb54b 100644
--- a/src/gui/accessible/qaccessible_win.cpp
+++ b/src/gui/accessible/qaccessible_win.cpp
@@ -353,8 +353,8 @@ void QAccessible::updateAccessibility(QObject *o, int who, Event reason)
     static PtrNotifyWinEvent ptrNotifyWinEvent = 0;
     static bool resolvedNWE = false;
     if (!resolvedNWE) {
-        resolvedNWE = true;
         ptrNotifyWinEvent = (PtrNotifyWinEvent)QSystemLibrary::resolve(QLatin1String("user32"), "NotifyWinEvent");
+        resolvedNWE = true;
     }
     if (!ptrNotifyWinEvent)
         return;
diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp
index 30f5f18..45f6164 100644
--- a/src/gui/dialogs/qfiledialog_win.cpp
+++ b/src/gui/dialogs/qfiledialog_win.cpp
@@ -97,7 +97,6 @@ static void qt_win_resolve_libs()
         }
 #endif
 
-        triedResolve = true;
 #if !defined(Q_WS_WINCE)
         QSystemLibrary lib(QLatin1String("shell32"));
         ptrSHBrowseForFolder = (PtrSHBrowseForFolder)lib.resolve("SHBrowseForFolderW");
@@ -112,6 +111,8 @@ static void qt_win_resolve_libs()
         if (ptrSHBrowseForFolder && ptrSHGetPathFromIDList && ptrSHGetMalloc)
             qt_priv_ptr_valid = true;
 #endif
+
+        triedResolve = true;
     }
 }
 
diff --git a/src/gui/dialogs/qwizard_win.cpp b/src/gui/dialogs/qwizard_win.cpp
index 9ea114c..00ebbfd 100644
--- a/src/gui/dialogs/qwizard_win.cpp
+++ b/src/gui/dialogs/qwizard_win.cpp
@@ -705,7 +705,6 @@ bool QVistaHelper::resolveSymbols()
 {
     static bool tried = false;
     if (!tried) {
-        tried = true;
         QSystemLibrary dwmLib(L"dwmapi");
         pDwmIsCompositionEnabled =
             (PtrDwmIsCompositionEnabled)dwmLib.resolve("DwmIsCompositionEnabled");
@@ -727,6 +726,7 @@ bool QVistaHelper::resolveSymbols()
             pDrawThemeTextEx = (PtrDrawThemeTextEx)themeLib.resolve("DrawThemeTextEx");
             pSetWindowThemeAttribute = (PtrSetWindowThemeAttribute)themeLib.resolve("SetWindowThemeAttribute");
         }
+        tried = true;
     }
 
     return (
diff --git a/src/gui/image/qpixmap_mac.cpp b/src/gui/image/qpixmap_mac.cpp
index 47b6eef..aa1571b 100644
--- a/src/gui/image/qpixmap_mac.cpp
+++ b/src/gui/image/qpixmap_mac.cpp
@@ -752,7 +752,8 @@ static PtrglReadPixels ptrglReadPixels = 0;
 
 static bool resolveOpenGLSymbols()
 {
-    if (ptrCGLChoosePixelFormat == 0) {
+    static bool triedResolve = false;
+    if (!triedResolve) {
         QLibrary library(QLatin1String("/System/Library/Frameworks/OpenGL.framework/OpenGL"));
         ptrCGLChoosePixelFormat = (PtrCGLChoosePixelFormat)(library.resolve("CGLChoosePixelFormat"));
         ptrCGLClearDrawable = (PtrCGLClearDrawable)(library.resolve("CGLClearDrawable"));
@@ -765,6 +766,7 @@ static bool resolveOpenGLSymbols()
         ptrglPixelStorei = (PtrglPixelStorei)(library.resolve("glPixelStorei"));
         ptrglReadBuffer = (PtrglReadBuffer)(library.resolve("glReadBuffer"));
         ptrglReadPixels = (PtrglReadPixels)(library.resolve("glReadPixels"));
+        triedResolve = true;
     }
     return ptrCGLChoosePixelFormat && ptrCGLClearDrawable && ptrCGLCreateContext
         && ptrCGLDestroyContext && ptrCGLDestroyPixelFormat && ptrCGLSetCurrentContext
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index bca3acc..b84fe56 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -218,9 +218,9 @@ static bool aygResolved = false;
 static void resolveAygLibs()
 {
     if (!aygResolved) {
-        aygResolved = true;
         QSystemLibrary ayglib(QLatin1String("aygshell"));
         ptrRecognizeGesture = (AygRecognizeGesture) ayglib.resolve("SHRecognizeGesture");
+        aygResolved = true;
     }
 }
 #endif // QT_NO_GESTURES
@@ -2371,15 +2371,14 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa
                     break;
                 }
 
+#if !defined(Q_OS_WINCE)
                 typedef LRESULT (WINAPI *PtrLresultFromObject)(REFIID, WPARAM, LPUNKNOWN);
                 static PtrLresultFromObject ptrLresultFromObject = 0;
                 static bool oleaccChecked = false;
-
                 if (!oleaccChecked) {
+                    QSystemLibrary oleacclib(QLatin1String("oleacc"));
+                    ptrLresultFromObject = (PtrLresultFromObject)oleacclib.resolve("LresultFromObject");
                     oleaccChecked = true;
-#if !defined(Q_OS_WINCE)
-                    ptrLresultFromObject = (PtrLresultFromObject)QSystemLibrary::resolve(QLatin1String("oleacc"), "LresultFromObject");
-#endif
                 }
                 if (ptrLresultFromObject) {
                     QAccessibleInterface *acc = QAccessible::queryAccessibleInterface(widget);
@@ -2396,6 +2395,7 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa
                     if (res > 0)
                         RETURN(res);
                 }
+#endif
             }
             result = false;
             break;
@@ -3181,8 +3181,8 @@ bool QETWidget::translateMouseEvent(const MSG &msg)
 
             if (curWin != 0) {
                 if (!trackMouseEventLookup) {
-                    trackMouseEventLookup = true;
                     ptrTrackMouseEvent = (PtrTrackMouseEvent)QSystemLibrary::resolve(QLatin1String("comctl32"), "_TrackMouseEvent");
+                    trackMouseEventLookup = true;
                 }
                 if (ptrTrackMouseEvent && !qApp->d_func()->inPopupMode()) {
                     // We always have to set the tracking, since
diff --git a/src/gui/kernel/qguifunctions_wince.cpp b/src/gui/kernel/qguifunctions_wince.cpp
index 78dc469..ae2ca04 100644
--- a/src/gui/kernel/qguifunctions_wince.cpp
+++ b/src/gui/kernel/qguifunctions_wince.cpp
@@ -125,17 +125,16 @@ static AygInitDialog ptrAygInitDialog = 0;
 static AygFullScreen ptrAygFullScreen = 0;
 static AygSHSipInfo  ptrAygSHSipInfo  = 0;
 static AygSHDoneButton ptrAygSHDoneButton = 0;
-static bool aygResolved = false;
-
 static void resolveAygLibs()
 {
+    static bool aygResolved = false;
     if (!aygResolved) {
-        aygResolved = true;
         QLibrary ayglib(QLatin1String("aygshell"));
         ptrAygInitDialog = (AygInitDialog) ayglib.resolve("SHInitDialog");
         ptrAygFullScreen = (AygFullScreen) ayglib.resolve("SHFullScreen");
         ptrAygSHSipInfo  = (AygSHSipInfo)  ayglib.resolve("SHSipInfo");
         ptrAygSHDoneButton = (AygSHDoneButton) ayglib.resolve("SHDoneButton");
+        aygResolved = true;
     }
 }
 
diff --git a/src/gui/kernel/qmime_mac.cpp b/src/gui/kernel/qmime_mac.cpp
index 8b47d8e..e92bd49 100644
--- a/src/gui/kernel/qmime_mac.cpp
+++ b/src/gui/kernel/qmime_mac.cpp
@@ -520,13 +520,15 @@ static PtrGraphicsExportDoExport ptrGraphicsExportDoExport = 0;
 
 static bool resolveMimeQuickTimeSymbols()
 {
-    if (ptrGraphicsImportSetDataHandle == 0) {
+    static bool triedResolve = false;
+    if (!triedResolve) {
         QLibrary library(QLatin1String("/System/Library/Frameworks/QuickTime.framework/QuickTime"));
         ptrGraphicsImportSetDataHandle = reinterpret_cast<PtrGraphicsImportSetDataHandle>(library.resolve("GraphicsImportSetDataHandle"));
         ptrGraphicsImportCreateCGImage = reinterpret_cast<PtrGraphicsImportCreateCGImage>(library.resolve("GraphicsImportCreateCGImage"));
         ptrGraphicsExportSetInputCGImage = reinterpret_cast<PtrGraphicsExportSetInputCGImage>(library.resolve("GraphicsExportSetInputCGImage"));
         ptrGraphicsExportSetOutputHandle = reinterpret_cast<PtrGraphicsExportSetOutputHandle>(library.resolve("GraphicsExportSetOutputHandle"));
         ptrGraphicsExportDoExport = reinterpret_cast<PtrGraphicsExportDoExport>(library.resolve("GraphicsExportDoExport"));
+        triedResolve = true;
     }
 
     return ptrGraphicsImportSetDataHandle != 0
diff --git a/src/gui/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp
index b894eb4..f991cbc 100644
--- a/src/gui/styles/qwindowsvistastyle.cpp
+++ b/src/gui/styles/qwindowsvistastyle.cpp
@@ -2586,7 +2586,6 @@ bool QWindowsVistaStylePrivate::resolveSymbols()
 {
     static bool tried = false;
     if (!tried) {
-        tried = true;
         QSystemLibrary themeLib(QLatin1String("uxtheme"));
         pSetWindowTheme         = (PtrSetWindowTheme        )themeLib.resolve("SetWindowTheme");
         pIsThemePartDefined     = (PtrIsThemePartDefined    )themeLib.resolve("IsThemePartDefined");
@@ -2611,6 +2610,7 @@ bool QWindowsVistaStylePrivate::resolveSymbols()
         pGetThemeString         = (PtrGetThemeString        )themeLib.resolve("GetThemeString");
         pGetThemeTransitionDuration = (PtrGetThemeTransitionDuration)themeLib.resolve("GetThemeTransitionDuration");
         pGetThemePropertyOrigin = (PtrGetThemePropertyOrigin)themeLib.resolve("GetThemePropertyOrigin");
+        tried = true;
     }
     return pGetThemeTransitionDuration != 0;
 }
diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp
index 3c33df3..dd7f1f6 100644
--- a/src/gui/styles/qwindowsxpstyle.cpp
+++ b/src/gui/styles/qwindowsxpstyle.cpp
@@ -343,7 +343,6 @@ bool QWindowsXPStylePrivate::resolveSymbols()
 {
     static bool tried = false;
     if (!tried) {
-        tried = true;
         QSystemLibrary themeLib(QLatin1String("uxtheme"));
         pIsAppThemed = (PtrIsAppThemed)themeLib.resolve("IsAppThemed");
         if (pIsAppThemed) {
@@ -372,6 +371,7 @@ bool QWindowsXPStylePrivate::resolveSymbols()
             pGetThemeDocumentationProperty         = (PtrGetThemeDocumentationProperty        )themeLib.resolve("GetThemeDocumentationProperty");
             pIsThemeBackgroundPartiallyTransparent = (PtrIsThemeBackgroundPartiallyTransparent)themeLib.resolve("IsThemeBackgroundPartiallyTransparent");
         }
+        tried = true;
     }
 
     return pIsAppThemed != 0;
diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp
index fc11387..bb5e041 100644
--- a/src/gui/text/qfontengine_win.cpp
+++ b/src/gui/text/qfontengine_win.cpp
@@ -138,8 +138,11 @@ static void resolveGetCharWidthI()
 {
     if (resolvedGetCharWidthI)
         return;
+
+    QSystemLibrary gdi32(QLatin1String("gdi32"));
+    ptrGetCharWidthI = (PtrGetCharWidthI)gdi32.resolve("GetCharWidthI");
+
     resolvedGetCharWidthI = true;
-    ptrGetCharWidthI = (PtrGetCharWidthI)QSystemLibrary::resolve(QLatin1String("gdi32"), "GetCharWidthI");
 }
 #endif // !defined(Q_WS_WINCE)
 
diff --git a/src/gui/widgets/qmenu_wince.cpp b/src/gui/widgets/qmenu_wince.cpp
index b0c6c1b..d45daf8 100644
--- a/src/gui/widgets/qmenu_wince.cpp
+++ b/src/gui/widgets/qmenu_wince.cpp
@@ -111,10 +111,10 @@ static AygEnableSoftKey ptrEnableSoftKey = 0;
 static void resolveAygLibs()
 {
     if (!aygResolved) {
-        aygResolved = true;
         QLibrary aygLib(QLatin1String("aygshell"));
         ptrCreateMenuBar = (AygCreateMenuBar) aygLib.resolve("SHCreateMenuBar");
         ptrEnableSoftKey = (AygEnableSoftKey) aygLib.resolve("SHEnableSoftkey");
+        aygResolved = true;
     }
 }
 
diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp
index 5f273d7..a624468 100644
--- a/src/network/kernel/qnetworkinterface_win.cpp
+++ b/src/network/kernel/qnetworkinterface_win.cpp
@@ -63,16 +63,14 @@ static void resolveLibs()
 {
     // try to find the functions we need from Iphlpapi.dll
     static bool done = false;
-
     if (!done) {
-        done = true;
-
         QSystemLibrary iphlpapi(QLatin1String("iphlpapi"));
         if (iphlpapi.load()) {
             ptrGetAdaptersInfo = (PtrGetAdaptersInfo)iphlpapi.resolve("GetAdaptersInfo");
             ptrGetAdaptersAddresses = (PtrGetAdaptersAddresses)iphlpapi.resolve("GetAdaptersAddresses");
             ptrGetNetworkParams = (PtrGetNetworkParams)iphlpapi.resolve("GetNetworkParams");
         }
+        done = true;
     }
 }
 
-- 
cgit v0.12