free EGL resources associated to a thread when it terminates
destroyed but current-to-a-thread resources are only destroyed when they're made not-current; however, we were not destroying those when the thread itself terminated, causing these resources to be leaked forever. we now install a tls-key destructor that takes care of this by calling eglReleaseThread upon thread termination. Bug: 9209776 Change-Id: I88298a34e3a27488eb81eab76717715569c7d57c
This commit is contained in:
parent
9e3cb55b8f
commit
4e620ddce3
@ -1177,6 +1177,11 @@ EGLBoolean eglReleaseThread(void)
|
|||||||
{
|
{
|
||||||
clearError();
|
clearError();
|
||||||
|
|
||||||
|
#if EGL_TRACE
|
||||||
|
if (getEGLDebugLevel() > 0)
|
||||||
|
GLTrace_eglReleaseThread();
|
||||||
|
#endif
|
||||||
|
|
||||||
// If there is context bound to the thread, release it
|
// If there is context bound to the thread, release it
|
||||||
egl_display_t::loseCurrent(get_context(getContext()));
|
egl_display_t::loseCurrent(get_context(getContext()));
|
||||||
|
|
||||||
@ -1184,12 +1189,7 @@ EGLBoolean eglReleaseThread(void)
|
|||||||
if (cnx->dso && cnx->egl.eglReleaseThread) {
|
if (cnx->dso && cnx->egl.eglReleaseThread) {
|
||||||
cnx->egl.eglReleaseThread();
|
cnx->egl.eglReleaseThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
egl_tls_t::clearTLS();
|
egl_tls_t::clearTLS();
|
||||||
#if EGL_TRACE
|
|
||||||
if (getEGLDebugLevel() > 0)
|
|
||||||
GLTrace_eglReleaseThread();
|
|
||||||
#endif
|
|
||||||
return EGL_TRUE;
|
return EGL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,8 +29,8 @@
|
|||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
pthread_key_t egl_tls_t::sKey = -1;
|
pthread_key_t egl_tls_t::sKey = TLS_KEY_NOT_INITIALIZED;
|
||||||
pthread_mutex_t egl_tls_t::sLockKey = PTHREAD_MUTEX_INITIALIZER;
|
pthread_once_t egl_tls_t::sOnceKey = PTHREAD_ONCE_INIT;
|
||||||
|
|
||||||
egl_tls_t::egl_tls_t()
|
egl_tls_t::egl_tls_t()
|
||||||
: error(EGL_SUCCESS), ctx(0), logCallWithNoContext(EGL_TRUE) {
|
: error(EGL_SUCCESS), ctx(0), logCallWithNoContext(EGL_TRUE) {
|
||||||
@ -59,12 +59,12 @@ const char *egl_tls_t::egl_strerror(EGLint err) {
|
|||||||
|
|
||||||
void egl_tls_t::validateTLSKey()
|
void egl_tls_t::validateTLSKey()
|
||||||
{
|
{
|
||||||
if (sKey == -1) {
|
struct TlsKeyInitializer {
|
||||||
pthread_mutex_lock(&sLockKey);
|
static void create() {
|
||||||
if (sKey == -1)
|
pthread_key_create(&sKey, (void (*)(void*))&eglReleaseThread);
|
||||||
pthread_key_create(&sKey, NULL);
|
}
|
||||||
pthread_mutex_unlock(&sLockKey);
|
};
|
||||||
}
|
pthread_once(&sOnceKey, TlsKeyInitializer::create);
|
||||||
}
|
}
|
||||||
|
|
||||||
void egl_tls_t::setErrorEtcImpl(
|
void egl_tls_t::setErrorEtcImpl(
|
||||||
@ -104,11 +104,11 @@ egl_tls_t* egl_tls_t::getTLS() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void egl_tls_t::clearTLS() {
|
void egl_tls_t::clearTLS() {
|
||||||
if (sKey != -1) {
|
if (sKey != TLS_KEY_NOT_INITIALIZED) {
|
||||||
egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey);
|
egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey);
|
||||||
if (tls) {
|
if (tls) {
|
||||||
delete tls;
|
|
||||||
pthread_setspecific(sKey, 0);
|
pthread_setspecific(sKey, 0);
|
||||||
|
delete tls;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,10 +120,13 @@ void egl_tls_t::clearError() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EGLint egl_tls_t::getError() {
|
EGLint egl_tls_t::getError() {
|
||||||
if (sKey == -1)
|
if (sKey == TLS_KEY_NOT_INITIALIZED) {
|
||||||
return EGL_SUCCESS;
|
return EGL_SUCCESS;
|
||||||
|
}
|
||||||
egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey);
|
egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey);
|
||||||
if (!tls) return EGL_SUCCESS;
|
if (!tls) {
|
||||||
|
return EGL_SUCCESS;
|
||||||
|
}
|
||||||
EGLint error = tls->error;
|
EGLint error = tls->error;
|
||||||
tls->error = EGL_SUCCESS;
|
tls->error = EGL_SUCCESS;
|
||||||
return error;
|
return error;
|
||||||
@ -135,8 +138,9 @@ void egl_tls_t::setContext(EGLContext ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EGLContext egl_tls_t::getContext() {
|
EGLContext egl_tls_t::getContext() {
|
||||||
if (sKey == -1)
|
if (sKey == TLS_KEY_NOT_INITIALIZED) {
|
||||||
return EGL_NO_CONTEXT;
|
return EGL_NO_CONTEXT;
|
||||||
|
}
|
||||||
egl_tls_t* tls = (egl_tls_t *)pthread_getspecific(sKey);
|
egl_tls_t* tls = (egl_tls_t *)pthread_getspecific(sKey);
|
||||||
if (!tls) return EGL_NO_CONTEXT;
|
if (!tls) return EGL_NO_CONTEXT;
|
||||||
return tls->ctx;
|
return tls->ctx;
|
||||||
|
@ -30,8 +30,9 @@ namespace android {
|
|||||||
class DbgContext;
|
class DbgContext;
|
||||||
|
|
||||||
class egl_tls_t {
|
class egl_tls_t {
|
||||||
|
enum { TLS_KEY_NOT_INITIALIZED = -1 };
|
||||||
static pthread_key_t sKey;
|
static pthread_key_t sKey;
|
||||||
static pthread_mutex_t sLockKey;
|
static pthread_once_t sOnceKey;
|
||||||
|
|
||||||
EGLint error;
|
EGLint error;
|
||||||
EGLContext ctx;
|
EGLContext ctx;
|
||||||
|
@ -32,7 +32,7 @@ static pthread_key_t sTLSKey = -1;
|
|||||||
static pthread_once_t sPthreadOnceKey = PTHREAD_ONCE_INIT;
|
static pthread_once_t sPthreadOnceKey = PTHREAD_ONCE_INIT;
|
||||||
|
|
||||||
void createTLSKey() {
|
void createTLSKey() {
|
||||||
pthread_key_create(&sTLSKey, NULL);
|
pthread_key_create(&sTLSKey, (void (*)(void*))&releaseContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLTraceContext *getGLTraceContext() {
|
GLTraceContext *getGLTraceContext() {
|
||||||
|
Loading…
Reference in New Issue
Block a user