summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c58
-rw-r--r--OpenAL32/Include/alMain.h32
2 files changed, 65 insertions, 25 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 0cca6026..d7ddc15c 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -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;