aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32/alSource.c
diff options
context:
space:
mode:
Diffstat (limited to 'OpenAL32/alSource.c')
-rw-r--r--OpenAL32/alSource.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index 799ad855..024d7918 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -144,6 +144,19 @@ static inline bool IsPlayingOrPausedSeq(const ALsource *source)
return state == AL_PLAYING || state == AL_PAUSED;
}
+static ALenum GetSourceState(ALsource *source, ALvoice *voice)
+{
+ if(!voice)
+ {
+ ALenum state = AL_PLAYING;
+ if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALenum, &source->state, &state, AL_STOPPED,
+ almemory_order_acq_rel, almemory_order_acquire))
+ return AL_STOPPED;
+ return state;
+ }
+ return ATOMIC_LOAD(&source->state, almemory_order_acquire);
+}
+
static inline bool SourceShouldUpdate(const ALsource *source, const ALCcontext *context)
{
return IsPlayingOrPausedSeq(source) &&
@@ -686,11 +699,14 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
}
WriteLock(&Source->queue_lock);
- if(IsPlayingOrPausedSeq(Source))
{
- WriteUnlock(&Source->queue_lock);
- UnlockBuffersRead(device);
- SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE);
+ ALenum state = GetSourceState(Source, GetSourceVoice(Source, Context));
+ if(state == AL_PLAYING || state == AL_PAUSED)
+ {
+ WriteUnlock(&Source->queue_lock);
+ UnlockBuffersRead(device);
+ SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE);
+ }
}
if(buffer != NULL)
@@ -1245,7 +1261,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
return AL_TRUE;
case AL_SOURCE_STATE:
- *values = ATOMIC_LOAD_SEQ(&Source->state);
+ *values = GetSourceState(Source, GetSourceVoice(Source, Context));
return AL_TRUE;
case AL_BYTE_LENGTH_SOFT:
@@ -2950,7 +2966,7 @@ void UpdateAllSourceProps(ALCcontext *context)
{
ALvoice *voice = context->Voices[pos];
ALsource *source = ATOMIC_LOAD(&voice->Source, almemory_order_acquire);
- if(source != NULL && source->NeedsUpdate && IsPlayingOrPausedSeq(source))
+ if(source != NULL && source->NeedsUpdate)
{
source->NeedsUpdate = AL_FALSE;
UpdateSourceProps(source, num_sends);
@@ -2994,7 +3010,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
goto do_stop;
voice = GetSourceVoice(Source, Context);
- switch(ATOMIC_EXCHANGE(ALenum, &Source->state, AL_PLAYING, almemory_order_acq_rel))
+ switch(GetSourceState(Source, voice))
{
case AL_PLAYING:
assert(voice != NULL);
@@ -3012,6 +3028,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
*/
voice->Moving = AL_FALSE;
ATOMIC_STORE(&voice->Playing, true, almemory_order_release);
+ ATOMIC_STORE(&Source->state, AL_PLAYING, almemory_order_release);
goto done;
default:
@@ -3070,6 +3087,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
ATOMIC_STORE(&voice->Source, Source, almemory_order_relaxed);
ATOMIC_STORE(&voice->Playing, true, almemory_order_release);
+ ATOMIC_STORE(&Source->state, AL_PLAYING, almemory_order_release);
}
else if(state == AL_PAUSED)
{