st/wgl: add a stw_device::initialized field
authorBrian Paul <brianp@vmware.com>
Fri, 20 May 2016 20:24:59 +0000 (14:24 -0600)
committerBrian Paul <brianp@vmware.com>
Thu, 30 Jun 2016 18:43:50 +0000 (12:43 -0600)
Set when the stw_dev object's initialization is completed.  We test
for this in the window callback function to avoid potential crashes
on start-up in multi-threaded applications.

Reviewed-by: José Fonseca <jfonseca@vmware.com>
src/gallium/state_trackers/wgl/stw_device.c
src/gallium/state_trackers/wgl/stw_device.h
src/gallium/state_trackers/wgl/stw_framebuffer.c

index 287b937afe5ac8ea376f54f316159a9268b2d546..b57f96f2e872a809f4b05b56004d96b8ec9c1fe3 100644 (file)
@@ -116,6 +116,8 @@ stw_init(const struct stw_winsys *stw_winsys)
 
    stw_pixelformat_init();
 
+   stw_dev->initialized = true;
+
    return TRUE;
 
 error1:
index 15d66a24e5db6a3d95733326ffa01f29d6ea3162..ecf212d7cb690695f4b863ade01d6edca8d37485 100644 (file)
@@ -77,6 +77,8 @@ struct stw_device
 #ifdef DEBUG
    unsigned long memdbg_no;
 #endif
+
+   bool initialized;
 };
 
 
index 12636156a5e0e7492b1378a789289b0fae761847..d770adb2a55b2ced6ff2a6db008e8f1493cc6924 100644 (file)
@@ -203,32 +203,39 @@ stw_call_window_proc(int nCode, WPARAM wParam, LPARAM lParam)
    if (nCode < 0 || !stw_dev)
        return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
 
-   if (pParams->message == WM_WINDOWPOSCHANGED) {
-      /* We handle WM_WINDOWPOSCHANGED instead of WM_SIZE because according to
-       * http://blogs.msdn.com/oldnewthing/archive/2008/01/15/7113860.aspx
-       * WM_SIZE is generated from WM_WINDOWPOSCHANGED by DefWindowProc so it
-       * can be masked out by the application.
-       */
-      LPWINDOWPOS lpWindowPos = (LPWINDOWPOS)pParams->lParam;
-      if ((lpWindowPos->flags & SWP_SHOWWINDOW) ||
-          !(lpWindowPos->flags & SWP_NOMOVE) ||
-          !(lpWindowPos->flags & SWP_NOSIZE)) {
-         fb = stw_framebuffer_from_hwnd( pParams->hwnd );
-         if (fb) {
-            /* Size in WINDOWPOS includes the window frame, so get the size
-             * of the client area via GetClientRect.
-             */
-            stw_framebuffer_get_size(fb);
-            stw_framebuffer_unlock(fb);
+   /* We check that the stw_dev object is initialized before we try to do
+    * anything with it.  Otherwise, in multi-threaded programs there's a
+    * chance of executing this code before the stw_dev object is fully
+    * initialized.
+    */
+   if (stw_dev && stw_dev->initialized) {
+      if (pParams->message == WM_WINDOWPOSCHANGED) {
+         /* We handle WM_WINDOWPOSCHANGED instead of WM_SIZE because according
+          * to http://blogs.msdn.com/oldnewthing/archive/2008/01/15/7113860.aspx
+          * WM_SIZE is generated from WM_WINDOWPOSCHANGED by DefWindowProc so it
+          * can be masked out by the application.
+          */
+         LPWINDOWPOS lpWindowPos = (LPWINDOWPOS)pParams->lParam;
+         if ((lpWindowPos->flags & SWP_SHOWWINDOW) ||
+             !(lpWindowPos->flags & SWP_NOMOVE) ||
+             !(lpWindowPos->flags & SWP_NOSIZE)) {
+            fb = stw_framebuffer_from_hwnd( pParams->hwnd );
+            if (fb) {
+               /* Size in WINDOWPOS includes the window frame, so get the size
+                * of the client area via GetClientRect.
+                */
+               stw_framebuffer_get_size(fb);
+               stw_framebuffer_unlock(fb);
+            }
          }
       }
-   }
-   else if (pParams->message == WM_DESTROY) {
-      stw_lock_framebuffers(stw_dev);
-      fb = stw_framebuffer_from_hwnd_locked( pParams->hwnd );
-      if (fb)
-         stw_framebuffer_release_locked(fb);
-      stw_unlock_framebuffers(stw_dev);
+      else if (pParams->message == WM_DESTROY) {
+         stw_lock_framebuffers(stw_dev);
+         fb = stw_framebuffer_from_hwnd_locked( pParams->hwnd );
+         if (fb)
+            stw_framebuffer_release_locked(fb);
+         stw_unlock_framebuffers(stw_dev);
+      }
    }
 
    return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);