[Fix] (TLS): drop the context reference before clearing the slot at thread exit

This commit is contained in:
2026-10-10 04:14:14 -04:00
parent 3b01067a9b
commit a6028ff38a
3 changed files with 11 additions and 8 deletions
+7 -4
View File
@@ -1658,12 +1658,15 @@ namespace MobileGL::MG_State {
constinit thread_local CurrentGLContextSlot pGLContext;
// The reference that keeps the calling thread's pGLContext alive (Core.h). Registered for
// destruction on the thread's first assignment; at thread exit it clears the slot first, so
// whatever the context's destructor reaches sees no current context rather than one that is
// being destroyed.
// destruction on the thread's first assignment. At thread exit it drops the reference first,
// with the slot still naming the context - what destroying the SharedPtr this used to be did
// - and then clears the slot, so no pointer outlives the context.
struct CurrentGLContextOwner {
SharedPtr<GLState::GLContext> context;
~CurrentGLContextOwner() { pGLContext.m_context = nullptr; }
~CurrentGLContextOwner() {
context.reset();
pGLContext.m_context = nullptr;
}
};
namespace {
thread_local CurrentGLContextOwner tCurrentGLContextOwner;
+3 -3
View File
@@ -790,9 +790,9 @@ namespace MobileGL {
// every API level. This object is trivially destructible and constant-initialized, so a
// read is one TLS address computation and a load. The SharedPtr that keeps the context
// alive lives in a separate thread_local in Core.cpp, written only by the assignments
// below (eglMakeCurrent and the release edge, MG_State::Init(), tests); its destructor
// clears this pointer before it drops the reference, so a thread's exit leaves no
// dangling pointer behind.
// below (eglMakeCurrent and the release edge, MG_State::Init(), tests); at thread exit its
// destructor drops the reference and then clears this pointer, so no dangling pointer is
// left behind.
//
// Assignment, reset() and the SharedPtr conversions touch the owner and belong to the
// CALLING THREAD only: never assign through a reference to another thread's slot.
+1 -1
View File
@@ -234,7 +234,7 @@ namespace {
// restores the process-wide state even when a gtest assertion unwinds the test body.
struct ScopedDirectGLESTextureBindings {
ScopedDirectGLESTextureBindings():
previousContext(MobileGL::Move(MobileGL::MG_State::pGLContext)),
previousContext(MobileGL::MG_State::pGLContext.Take()),
previousFunctions(MobileGL::MG_Backend::DirectGLES::g_GLESFuncs),
previousActiveUnit(MobileGL::MG_Backend::DirectGLES::TextureImpl::g_activeTextureUnit),
previousCache(MobileGL::MG_Backend::DirectGLES::TextureImpl::g_boundTexturesCache),