diff options
-rw-r--r-- | Alc/ALc.c | 58 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 32 |
2 files changed, 65 insertions, 25 deletions
@@ -1361,11 +1361,41 @@ static ALvoid InitContext(ALCcontext *pContext) */ static ALCvoid FreeContext(ALCcontext *context) { + LockLists(); + if(context == GlobalContext) + GlobalContext = NULL; + UnlockLists(); + + if(context->SourceMap.size > 0) + { + ERR("FreeContext(%p): deleting %d Source(s)\n", context, context->SourceMap.size); + ReleaseALSources(context); + } + ResetUIntMap(&context->SourceMap); + + if(context->EffectSlotMap.size > 0) + { + ERR("FreeContext(%p): deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size); + ReleaseALAuxiliaryEffectSlots(context); + } + ResetUIntMap(&context->EffectSlotMap); + + free(context->ActiveSources); + context->ActiveSources = NULL; + context->MaxActiveSources = 0; + context->ActiveSourceCount = 0; + //Invalidate context memset(context, 0, sizeof(ALCcontext)); free(context); } +static void ALCcontext_Deref(ALCcontext *context) +{ + if(DecrementRef(&context->ref) == 0) + FreeContext(context); +} + /////////////////////////////////////////////////////// @@ -1998,6 +2028,8 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin ALContext = calloc(1, sizeof(ALCcontext)); if(ALContext) { + ALContext->ref = 1; + ALContext->MaxActiveSources = 256; ALContext->ActiveSources = malloc(sizeof(ALContext->ActiveSources[0]) * ALContext->MaxActiveSources); @@ -2059,11 +2091,6 @@ ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context) *list = (*list)->next; g_ulContextCount--; - if(context == tls_get(LocalContext)) - tls_set(LocalContext, NULL); - if(context == GlobalContext) - GlobalContext = NULL; - Device = context->Device; LockDevice(Device); for(i = 0;i < Device->NumContexts;i++) @@ -2084,26 +2111,7 @@ ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context) } UnlockLists(); - if(context->SourceMap.size > 0) - { - ERR("alcDestroyContext(): deleting %d Source(s)\n", context->SourceMap.size); - ReleaseALSources(context); - } - ResetUIntMap(&context->SourceMap); - - if(context->EffectSlotMap.size > 0) - { - ERR("alcDestroyContext(): deleting %d AuxiliaryEffectSlot(s)\n", context->EffectSlotMap.size); - ReleaseALAuxiliaryEffectSlots(context); - } - ResetUIntMap(&context->EffectSlotMap); - - free(context->ActiveSources); - context->ActiveSources = NULL; - context->MaxActiveSources = 0; - context->ActiveSourceCount = 0; - - FreeContext(context); + ALCcontext_Deref(context); } diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 2f30a953..0a006ee9 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -229,6 +229,36 @@ void *GetSymbol(void *handle, const char *name); #endif +#ifdef __GNUC__ +typedef ALuint RefCount; +static __inline RefCount IncrementRef(volatile RefCount *ptr) +{ return __sync_add_and_fetch(ptr, 1); } +static __inline RefCount DecrementRef(volatile RefCount *ptr) +{ return __sync_sub_and_fetch(ptr, 1); } + +#elif defined(_WIN32) + +typedef LONG RefCount; +static __inline RefCount IncrementRef(volatile RefCount *ptr) +{ return InterlockedInrement(ptr); } +static __inline RefCount DecrementRef(volatile RefCount *ptr) +{ return InterlockedDecrement(ptr); } + +#elif defined(__APPLE__) + +#include <libkern/OSAtomic.h> + +typedef int32_t RefCount; +static __inline RefCount IncrementRef(volatile RefCount *ptr) +{ return OSAtomicIncrement32Barrier(ptr); } +static __inline RefCount DecrementRef(volatile RefCount *ptr) +{ return OSAtomicDecrement32Barrier(ptr); } + +#else +#error "No atomic functions available on this platform!" +#endif + + #include "alListener.h" #include "alu.h" @@ -477,6 +507,8 @@ struct ALCdevice_struct struct ALCcontext_struct { + volatile RefCount ref; + ALlistener Listener; UIntMap SourceMap; |