OSDN Git Service

Protect the displays global map
authorGreg Hartman <ghartman@google.com>
Tue, 10 Nov 2015 02:10:30 +0000 (18:10 -0800)
committerNicolas Capens <capn@google.com>
Tue, 10 Nov 2015 17:46:09 +0000 (17:46 +0000)
Bug 25597090

Change-Id: Ie6bc4f55b5105a3e75cdc1b636f3e5716c10cc61
Reviewed-on: https://swiftshader-review.googlesource.com/4240
Tested-by: Greg Hartman <ghartman@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
src/OpenGL/libEGL/Display.cpp

index 3fd96bb..8715d95 100644 (file)
@@ -19,6 +19,7 @@
 #include "libEGL/Surface.h"
 #include "libEGL/Context.hpp"
 #include "common/debug.h"
+#include "Common/MutexLock.hpp"
 
 #if defined(__unix__) && !defined(__ANDROID__)
 #include "Main/libX11.hpp"
 namespace egl
 {
 typedef std::map<EGLNativeDisplayType, Display*> DisplayMap;
-DisplayMap displays;
+
+// Protects the global displays map.
+sw::BackoffLock displays_lock;
+
+// The order of construction of globals is undefined in C++.
+// This function ensures that construction has completed before we attempt
+// to access displays.
+DisplayMap* getDisplays() {
+  static DisplayMap displays;
+  return &displays;
+}
 
 egl::Display *Display::getPlatformDisplay(EGLenum platform, EGLNativeDisplayType displayId)
 {
@@ -81,15 +92,19 @@ egl::Display *Display::getPlatformDisplay(EGLenum platform, EGLNativeDisplayType
         }
     #endif
 
-    if(displays.find(displayId) != displays.end())
+    egl::Display *rval;
+    displays_lock.lock();
+    DisplayMap* displays = getDisplays();
+    if (displays->find(displayId) != displays->end())
     {
-        return displays[displayId];
-    }
-
-    egl::Display *display = new egl::Display(platform, displayId);
+        rval = (*displays)[displayId];
+    } else {
+        rval = new egl::Display(platform, displayId);
 
-    displays[displayId] = display;
-    return display;
+        (*displays)[displayId] = rval;
+    }
+    displays_lock.unlock();
+    return rval;
 }
 
 Display::Display(EGLenum platform, EGLNativeDisplayType displayId) : platform(platform), displayId(displayId)
@@ -102,7 +117,9 @@ Display::~Display()
 {
     terminate();
 
-       displays.erase(displayId);
+    displays_lock.lock();
+    getDisplays()->erase(displayId);
+    displays_lock.unlock();
 }
 
 static void cpuid(int registers[4], int info)