diff options
author | 2016-05-20 10:47:07 -0700 | |
---|---|---|
committer | 2016-05-21 14:07:25 -0700 | |
commit | 3aa75f95f23df87cf74ddefe0d3f90b1484ff95e (patch) | |
tree | 5fd9e103c2bfbd758670d0db781d08b1d3f5e4af /opengl/libagl/egl.cpp | |
parent | b59de7fa32b0bcaf52d00290d075d8e9c8f2dd2b (diff) |
Ensure memory ordering around libagl and EGL refcount operations
The android_atomic_inc/android_atomic_dec functions don't impose
sufficient memory ordering. Using them for object refcounting could
allow an object to be destroyed prior to writes by a different thread
being visible.
Bug: 28820690
Change-Id: Ie018091035174255a22ebc52852528cdaec2d648
Diffstat (limited to 'opengl/libagl/egl.cpp')
-rw-r--r-- | opengl/libagl/egl.cpp | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 7560d8fdf0..92139e9735 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -16,6 +16,7 @@ */ #include <assert.h> +#include <atomic> #include <errno.h> #include <stdlib.h> #include <stdio.h> @@ -27,7 +28,6 @@ #include <sys/mman.h> #include <cutils/log.h> -#include <cutils/atomic.h> #include <utils/threads.h> #include <ui/ANativeObjectBase.h> @@ -107,8 +107,8 @@ struct egl_display_t return ((uintptr_t(dpy)-1U) >= NUM_DISPLAYS) ? EGL_FALSE : EGL_TRUE; } - NativeDisplayType type; - volatile int32_t initialized; + NativeDisplayType type; + std::atomic_size_t initialized; }; static egl_display_t gDisplays[NUM_DISPLAYS]; @@ -1429,7 +1429,7 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) EGLBoolean res = EGL_TRUE; egl_display_t& d = egl_display_t::get_display(dpy); - if (android_atomic_inc(&d.initialized) == 0) { + if (d.initialized.fetch_add(1, std::memory_order_acquire) == 0) { // initialize stuff here if needed //pthread_mutex_lock(&gInitMutex); //pthread_mutex_unlock(&gInitMutex); @@ -1449,7 +1449,8 @@ EGLBoolean eglTerminate(EGLDisplay dpy) EGLBoolean res = EGL_TRUE; egl_display_t& d = egl_display_t::get_display(dpy); - if (android_atomic_dec(&d.initialized) == 1) { + if (d.initialized.fetch_sub(1, std::memory_order_release) == 1) { + std::atomic_thread_fence(std::memory_order_acquire); // TODO: destroy all resources (surfaces, contexts, etc...) //pthread_mutex_lock(&gInitMutex); //pthread_mutex_unlock(&gInitMutex); |