]> git.saurik.com Git - wxWidgets.git/commitdiff
unload msimg32.dll earlier (before static cleanup time) to avoid lockups when wx...
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 26 Nov 2007 21:27:17 +0000 (21:27 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 26 Nov 2007 21:27:17 +0000 (21:27 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50263 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/msw/dc.cpp

index fa9c434fb42869c77117581e0b8f4ffd376f414d..0801815ebf277f650057f3f17b53980ab2ad7374 100644 (file)
@@ -238,14 +238,37 @@ public:
         return m_dll.IsLoaded() ? m_dll.GetSymbol(name) : NULL;
     }
 
         return m_dll.IsLoaded() ? m_dll.GetSymbol(name) : NULL;
     }
 
+    void Unload()
+    {
+        if ( m_dll.IsLoaded() )
+        {
+            m_dll.Unload();
+        }
+    }
+
 private:
     wxDynamicLibrary m_dll;
     const wxChar *m_dllName;
 };
 
 private:
     wxDynamicLibrary m_dll;
     const wxChar *m_dllName;
 };
 
-static wxOnceOnlyDLLLoader wxGDI32DLL(_T("gdi32"));
 static wxOnceOnlyDLLLoader wxMSIMG32DLL(_T("msimg32"));
 
 static wxOnceOnlyDLLLoader wxMSIMG32DLL(_T("msimg32"));
 
+// we must ensure that DLLs are unloaded before the static objects cleanup time
+// because we may hit the notorious DllMain() dead lock in this case if wx is
+// used as a DLL (attempting to unload another DLL from inside DllMain() hangs
+// under Windows because it tries to reacquire the same lock)
+class wxGDIDLLsCleanupModule : public wxModule
+{
+public:
+    virtual bool OnInit() { return true; }
+    virtual void OnExit() { wxMSIMG32DLL.Unload(); }
+
+private:
+    DECLARE_DYNAMIC_CLASS(wxGDIDLLsCleanupModule)
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxGDIDLLsCleanupModule, wxModule)
+
 #endif // wxUSE_DYNLIB_CLASS
 
 // ===========================================================================
 #endif // wxUSE_DYNLIB_CLASS
 
 // ===========================================================================
@@ -2694,9 +2717,9 @@ static DWORD wxGetDCLayout(HDC hdc)
 {
     typedef DWORD (WINAPI *GetLayout_t)(HDC);
     static GetLayout_t
 {
     typedef DWORD (WINAPI *GetLayout_t)(HDC);
     static GetLayout_t
-        pfnGetLayout = (GetLayout_t)wxGDI32DLL.GetSymbol(_T("GetLayout"));
+        wxDL_INIT_FUNC(s_pfn, GetLayout, wxDynamicLibrary(_T("gdi32.dll")));
 
 
-    return pfnGetLayout ? pfnGetLayout(hdc) : (DWORD)-1;
+    return s_pfnGetLayout ? s_pfnGetLayout(hdc) : (DWORD)-1;
 }
 
 wxLayoutDirection wxDC::GetLayoutDirection() const
 }
 
 wxLayoutDirection wxDC::GetLayoutDirection() const
@@ -2713,8 +2736,8 @@ void wxDC::SetLayoutDirection(wxLayoutDirection dir)
 {
     typedef DWORD (WINAPI *SetLayout_t)(HDC, DWORD);
     static SetLayout_t
 {
     typedef DWORD (WINAPI *SetLayout_t)(HDC, DWORD);
     static SetLayout_t
-        pfnSetLayout = (SetLayout_t)wxGDI32DLL.GetSymbol(_T("SetLayout"));
-    if ( !pfnSetLayout )
+        wxDL_INIT_FUNC(s_pfn, SetLayout, wxDynamicLibrary(_T("gdi32.dll")));
+    if ( !s_pfnSetLayout )
         return;
 
     if ( dir == wxLayout_Default )
         return;
 
     if ( dir == wxLayout_Default )
@@ -2730,7 +2753,7 @@ void wxDC::SetLayoutDirection(wxLayoutDirection dir)
     else
         layout &= ~LAYOUT_RTL;
 
     else
         layout &= ~LAYOUT_RTL;
 
-    pfnSetLayout(GetHdc(), layout);
+    s_pfnSetLayout(GetHdc(), layout);
 }
 
 #else // !wxUSE_DYNLIB_CLASS
 }
 
 #else // !wxUSE_DYNLIB_CLASS