diff options
author | Chris Robinson <[email protected]> | 2011-08-29 23:55:24 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2011-08-29 23:55:24 -0700 |
commit | f02d9e22d755e69baab00f1d7ddceced6bac8136 (patch) | |
tree | 5c424026e216af09cddeb07f96472a2ed299ff02 | |
parent | cc67f4589256efceb17c58673159b3e687ec0436 (diff) |
Do a pointer exchange when replacing the source buffer queue
-rw-r--r-- | OpenAL32/Include/alMain.h | 16 | ||||
-rw-r--r-- | OpenAL32/alSource.c | 33 |
2 files changed, 33 insertions, 16 deletions
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 454bb715..57eee33d 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -235,6 +235,10 @@ static __inline int ExchangeInt(volatile int *ptr, int newval) { return __sync_lock_test_and_set(ptr, newval); } +static __inline void *ExchangePtr(void *volatile*ptr, void *newval) +{ + return __sync_lock_test_and_set(ptr, newval); +} static __inline ALboolean CompExchangeInt(volatile int *ptr, int oldval, int newval) { return __sync_bool_compare_and_swap(ptr, oldval, newval); @@ -258,6 +262,10 @@ static __inline int ExchangeInt(volatile int *ptr, int newval) } u = { ptr }; return InterlockedExchange(u.l, newval); } +static __inline void *ExchangePtr(void *volatile*ptr, void *newval) +{ + return InterlockedExchangePtr(ptr, newval); +} static __inline ALboolean CompExchangeInt(volatile int *ptr, int oldval, int newval) { union { @@ -286,6 +294,14 @@ static __inline int ExchangeInt(volatile int *ptr, int newval) } while(!OSAtomicCompareAndSwap32Barrier(oldval, newval, ptr)); return oldval; } +static __inline void *ExchangePtr(void *volatile*ptr, void *newval) +{ + void *oldval; + do { + oldval = *ptr; + } while(!OSAtomicCompareAndSwapPtrBarrier(oldval, newval, ptr)); + return oldval; +} static __inline ALboolean CompExchangeInt(volatile int *ptr, int oldval, int newval) { return OSAtomicCompareAndSwap32Barrier(oldval, newval, ptr); diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 3e8d2b6a..9d4f048c 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -559,22 +559,14 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source,ALenum eParam,ALint lValue) case AL_BUFFER: if(Source->state == AL_STOPPED || Source->state == AL_INITIAL) { + ALbufferlistitem *oldlist; ALbuffer *buffer = NULL; if(lValue == 0 || (buffer=LookupBuffer(device->BufferMap, lValue)) != NULL) { - // Remove all elements in the queue - while(Source->queue != NULL) - { - BufferListItem = Source->queue; - Source->queue = BufferListItem->next; - - if(BufferListItem->buffer) - DecrementRef(&BufferListItem->buffer->ref); - free(BufferListItem); - } Source->BuffersInQueue = 0; + Source->BuffersPlayed = 0; // Add the buffer to the queue (as long as it is NOT the NULL buffer) if(buffer != NULL) @@ -587,8 +579,10 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source,ALenum eParam,ALint lValue) BufferListItem->buffer = buffer; BufferListItem->next = NULL; BufferListItem->prev = NULL; + // Increment reference counter for buffer + IncrementRef(&buffer->ref); - Source->queue = BufferListItem; + oldlist = ExchangePtr((void**)&Source->queue, BufferListItem); Source->BuffersInQueue = 1; Source->NumChannels = ChannelsFromFmt(buffer->FmtChannels); @@ -597,18 +591,25 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source,ALenum eParam,ALint lValue) Source->Update = CalcSourceParams; else Source->Update = CalcNonAttnSourceParams; - - // Increment reference counter for buffer - IncrementRef(&buffer->ref); + Source->NeedsUpdate = AL_TRUE; } else { // Source is now in UNDETERMINED mode Source->lSourceType = AL_UNDETERMINED; + oldlist = ExchangePtr((void**)&Source->queue, NULL); } - Source->BuffersPlayed = 0; - Source->NeedsUpdate = AL_TRUE; + // Delete all previous elements in the queue + while(oldlist != NULL) + { + BufferListItem = oldlist; + oldlist = BufferListItem->next; + + if(BufferListItem->buffer) + DecrementRef(&BufferListItem->buffer->ref); + free(BufferListItem); + } } else alSetError(pContext, AL_INVALID_VALUE); |