diff options
author | Chris Robinson <[email protected]> | 2018-11-16 21:55:11 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2018-11-16 21:55:11 -0800 |
commit | ee8e6733e1bddb7ca9ed5b93a1407b7113a44e6e (patch) | |
tree | 03f9f092edf70f62e8d06a4eb815b502cb2c1fa3 /Alc/alc.cpp | |
parent | 8410e71a34fc286579573ab55dc94be83c48e55b (diff) |
Avoid using C-style TLS
Diffstat (limited to 'Alc/alc.cpp')
-rw-r--r-- | Alc/alc.cpp | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp index 04792498..05112e28 100644 --- a/Alc/alc.cpp +++ b/Alc/alc.cpp @@ -795,7 +795,22 @@ constexpr ALchar alExtList[] = std::atomic<ALCenum> LastNullDeviceError{ALC_NO_ERROR}; /* Thread-local current context */ -altss_t LocalContext; +std::atomic<void(*)(ALCcontext*)> ThreadCtxProc{nullptr}; +thread_local class ThreadCtx { + ALCcontext *ctx{nullptr}; + +public: + ~ThreadCtx() + { + auto destruct = ThreadCtxProc.load(); + if(destruct && ctx) + destruct(ctx); + ctx = nullptr; + } + + ALCcontext *get() const noexcept { return ctx; } + void set(ALCcontext *ctx_) noexcept { ctx = ctx_; } +} LocalContext; /* Process-wide current context */ std::atomic<ALCcontext*> GlobalContext{nullptr}; @@ -916,15 +931,12 @@ static void alc_deinit(void) __attribute__((destructor)); #error "No global initialization available on this platform!" #endif -static void ReleaseThreadCtx(void *ptr); +static void ReleaseThreadCtx(ALCcontext *ctx); static void alc_init(void) { - const char *str; - int ret; - LogFile = stderr; - str = getenv("__ALSOFT_HALF_ANGLE_CONES"); + const char *str{getenv("__ALSOFT_HALF_ANGLE_CONES")}; if(str && (strcasecmp(str, "true") == 0 || strtol(str, nullptr, 0) == 1)) ConeScale *= 0.5f; @@ -936,8 +948,7 @@ static void alc_init(void) if(str && (strcasecmp(str, "true") == 0 || strtol(str, nullptr, 0) == 1)) OverrideReverbSpeedOfSound = AL_TRUE; - ret = altss_create(&LocalContext, ReleaseThreadCtx); - assert(ret == althrd_success); + ThreadCtxProc = ReleaseThreadCtx; } static void alc_initconfig(void) @@ -1236,7 +1247,7 @@ static void alc_deinit_safe(void) FreeHrtfs(); FreeALConfig(); - altss_delete(LocalContext); + ThreadCtxProc = nullptr; if(LogFile != stderr) fclose(LogFile); @@ -2802,10 +2813,10 @@ static bool ReleaseContext(ALCcontext *context, ALCdevice *device) ALCcontext *origctx, *newhead; bool ret = true; - if(altss_get(LocalContext) == context) + if(LocalContext.get() == context) { WARN("%p released while current on thread\n", context); - altss_set(LocalContext, nullptr); + LocalContext.set(nullptr); ALCcontext_DecRef(context); } @@ -2858,9 +2869,8 @@ void ALCcontext_DecRef(ALCcontext *context) if(ref == 0) FreeContext(context); } -static void ReleaseThreadCtx(void *ptr) +static void ReleaseThreadCtx(ALCcontext *context) { - ALCcontext *context = static_cast<ALCcontext*>(ptr); uint ref = DecrementRef(&context->ref); TRACEREF("%p decreasing refcount to %u\n", context, ref); ERR("Context %p current for thread being destroyed, possible leak!\n", context); @@ -2901,7 +2911,7 @@ static ALCboolean VerifyContext(ALCcontext **context) */ ALCcontext *GetContextRef(void) { - ALCcontext *context{static_cast<ALCcontext*>(altss_get(LocalContext))}; + ALCcontext *context{LocalContext.get()}; if(context) ALCcontext_IncRef(context); else @@ -3920,7 +3930,7 @@ ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context) */ ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void) { - ALCcontext *Context{static_cast<ALCcontext*>(altss_get(LocalContext))}; + ALCcontext *Context{LocalContext.get()}; if(!Context) Context = GlobalContext.load(); return Context; } @@ -3931,7 +3941,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void) */ ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void) { - return static_cast<ALCcontext*>(altss_get(LocalContext)); + return LocalContext.get(); } @@ -3952,9 +3962,9 @@ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context) context = GlobalContext.exchange(context); if(context) ALCcontext_DecRef(context); - if((context=static_cast<ALCcontext*>(altss_get(LocalContext))) != nullptr) + if((context=LocalContext.get()) != nullptr) { - altss_set(LocalContext, nullptr); + LocalContext.set(nullptr); ALCcontext_DecRef(context); } @@ -3974,8 +3984,8 @@ ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context) return ALC_FALSE; } /* context's reference count is already incremented */ - ALCcontext *old{static_cast<ALCcontext*>(altss_get(LocalContext))}; - altss_set(LocalContext, context); + ALCcontext *old{LocalContext.get()}; + LocalContext.set(context); if(old) ALCcontext_DecRef(old); return ALC_TRUE; |