aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32/alSource.c
diff options
context:
space:
mode:
Diffstat (limited to 'OpenAL32/alSource.c')
-rw-r--r--OpenAL32/alSource.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index 4a50d217..0e98f2f5 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -642,8 +642,9 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
case AL_LOOPING:
CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
- Source->Looping = (ALboolean)*values;
- DO_UPDATEPROPS();
+ WriteLock(&Source->queue_lock);
+ ATOMIC_STORE(&Source->looping, *values);
+ WriteUnlock(&Source->queue_lock);
return AL_TRUE;
case AL_BUFFER:
@@ -1198,7 +1199,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
return AL_TRUE;
case AL_LOOPING:
- *values = Source->Looping;
+ *values = ATOMIC_LOAD(&Source->looping);
return AL_TRUE;
case AL_BUFFER:
@@ -1285,7 +1286,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
case AL_BUFFERS_PROCESSED:
ReadLock(&Source->queue_lock);
- if(Source->Looping || Source->SourceType != AL_STREAMING)
+ if(ATOMIC_LOAD(&Source->looping) || Source->SourceType != AL_STREAMING)
{
/* Buffers on a looping source are in a perpetual state of
* PENDING, so don't report any as PROCESSED */
@@ -2605,6 +2606,13 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
WriteLock(&source->queue_lock);
+ if(ATOMIC_LOAD(&source->looping) || source->SourceType != AL_STREAMING)
+ {
+ WriteUnlock(&source->queue_lock);
+ /* Trying to unqueue buffers on a looping or non-streaming source. */
+ SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
+ }
+
/* Find the new buffer queue head */
OldTail = ATOMIC_LOAD(&source->queue);
Current = ATOMIC_LOAD(&source->current_buffer);
@@ -2617,10 +2625,10 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint
OldTail = next;
}
}
- if(source->Looping || source->SourceType != AL_STREAMING || i != nb)
+ if(i != nb)
{
WriteUnlock(&source->queue_lock);
- /* Trying to unqueue pending buffers, or a buffer that wasn't queued. */
+ /* Trying to unqueue pending buffers. */
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
}
@@ -2693,7 +2701,6 @@ static void InitSourceParams(ALsource *Source)
Source->RefDistance = 1.0f;
Source->MaxDistance = FLT_MAX;
Source->RollOffFactor = 1.0f;
- Source->Looping = AL_FALSE;
Source->Gain = 1.0f;
Source->MinGain = 0.0f;
Source->MaxGain = 1.0f;
@@ -2741,6 +2748,8 @@ static void InitSourceParams(ALsource *Source)
ATOMIC_INIT(&Source->position, 0);
ATOMIC_INIT(&Source->position_fraction, 0);
+ ATOMIC_INIT(&Source->looping, AL_FALSE);
+
ATOMIC_INIT(&Source->Update, NULL);
ATOMIC_INIT(&Source->FreeList, NULL);
}
@@ -2832,7 +2841,6 @@ static void UpdateSourceProps(ALsource *source, ALuint num_sends, ALCcontext *co
almemory_order_relaxed);
}
ATOMIC_STORE(&props->HeadRelative, source->HeadRelative, almemory_order_relaxed);
- ATOMIC_STORE(&props->Looping, source->Looping, almemory_order_relaxed);
ATOMIC_STORE(&props->DistanceModel,
context->SourceDistanceModel ? source->DistanceModel : context->DistanceModel,
almemory_order_relaxed
@@ -3168,6 +3176,7 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device
ALuint readPos, readPosFrac;
ALuint totalBufferLen;
ALdouble offset = 0.0;
+ ALboolean looping;
ALuint refcount;
ReadLock(&Source->queue_lock);
@@ -3186,6 +3195,8 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device
readPos = ATOMIC_LOAD(&Source->position, almemory_order_relaxed);
readPosFrac = ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed);
+
+ looping = ATOMIC_LOAD(&Source->looping, almemory_order_relaxed);
} while(refcount != ReadRef(&device->MixCount));
while(BufferList != NULL)
@@ -3202,7 +3213,7 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device
}
assert(Buffer != NULL);
- if(Source->Looping)
+ if(looping)
readPos %= totalBufferLen;
else
{