summaryrefslogtreecommitdiffstats
path: root/opengl/libs/EGL/egl.cpp
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2010-02-05 16:17:01 -0800
committerMathias Agopian <mathias@google.com>2010-02-05 16:17:01 -0800
commit6099ab701e8a1e5b18c997cd913d17dc478bfed7 (patch)
treea09c444841acb97e0960dca66be3d697c7ee8358 /opengl/libs/EGL/egl.cpp
parent7722abe2591026e7db8910afa0431602723fc1e0 (diff)
downloadframeworks_base-6099ab701e8a1e5b18c997cd913d17dc478bfed7.zip
frameworks_base-6099ab701e8a1e5b18c997cd913d17dc478bfed7.tar.gz
frameworks_base-6099ab701e8a1e5b18c997cd913d17dc478bfed7.tar.bz2
fix [2189862] Race condition in eglIntialize and eglDestroy
there is now a lock protext a perticular display. it's held during initialization and destruction.
Diffstat (limited to 'opengl/libs/EGL/egl.cpp')
-rw-r--r--opengl/libs/EGL/egl.cpp19
1 files changed, 16 insertions, 3 deletions
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index d2f8ced..145e25e 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -166,7 +166,8 @@ struct egl_display_t {
uint32_t magic;
DisplayImpl disp[IMPL_NUM_IMPLEMENTATIONS];
EGLint numTotalConfigs;
- volatile int32_t refs;
+ uint32_t refs;
+ Mutex lock;
egl_display_t() : magic('_dpy'), numTotalConfigs(0) { }
~egl_display_t() { magic = 0; }
@@ -644,7 +645,9 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
egl_display_t * const dp = get_display(dpy);
if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
- if (android_atomic_inc(&dp->refs) > 0) {
+ Mutex::Autolock _l(dp->lock);
+
+ if (dp->refs > 0) {
if (major != NULL) *major = VERSION_MAJOR;
if (minor != NULL) *minor = VERSION_MINOR;
return EGL_TRUE;
@@ -728,6 +731,7 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
}
if (res == EGL_TRUE) {
+ dp->refs++;
if (major != NULL) *major = VERSION_MAJOR;
if (minor != NULL) *minor = VERSION_MINOR;
return EGL_TRUE;
@@ -743,7 +747,15 @@ EGLBoolean eglTerminate(EGLDisplay dpy)
egl_display_t* const dp = get_display(dpy);
if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
- if (android_atomic_dec(&dp->refs) != 1)
+
+ Mutex::Autolock _l(dp->lock);
+
+ if (dp->refs == 0) {
+ return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
+ }
+
+ // this is specific to Android, display termination is ref-counted.
+ if (dp->refs > 1)
return EGL_TRUE;
EGLBoolean res = EGL_FALSE;
@@ -767,6 +779,7 @@ EGLBoolean eglTerminate(EGLDisplay dpy)
// TODO: all egl_object_t should be marked for termination
+ dp->refs--;
dp->numTotalConfigs = 0;
clearTLS();
return res;