diff options
author | Chris Robinson <[email protected]> | 2016-05-10 23:42:44 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2016-05-10 23:42:44 -0700 |
commit | 21bc0f5ef8f0e410ea840061589b844d6e401afc (patch) | |
tree | 89b98336e44a3d9fe30640aecfcb2bf70d7a6251 | |
parent | 906a4bb22d6811615ccff417b6086fa36f310c00 (diff) |
Hold the buffer map lock while handling the buffer
-rw-r--r-- | OpenAL32/Include/alBuffer.h | 13 | ||||
-rw-r--r-- | OpenAL32/alBuffer.c | 43 | ||||
-rw-r--r-- | OpenAL32/alSource.c | 12 |
3 files changed, 64 insertions, 4 deletions
diff --git a/OpenAL32/Include/alBuffer.h b/OpenAL32/Include/alBuffer.h index 71fe7e30..4807dd16 100644 --- a/OpenAL32/Include/alBuffer.h +++ b/OpenAL32/Include/alBuffer.h @@ -106,10 +106,19 @@ void DeleteBuffer(ALCdevice *device, ALbuffer *buffer); ALenum LoadData(ALbuffer *buffer, ALuint freq, ALenum NewFormat, ALsizei frames, enum UserFmtChannels SrcChannels, enum UserFmtType SrcType, const ALvoid *data, ALsizei align, ALboolean storesrc); +inline void LockBuffersRead(ALCdevice *device) +{ LockUIntMapRead(&device->BufferMap); } +inline void UnlockBuffersRead(ALCdevice *device) +{ UnlockUIntMapRead(&device->BufferMap); } +inline void LockBuffersWrite(ALCdevice *device) +{ LockUIntMapWrite(&device->BufferMap); } +inline void UnlockBuffersWrite(ALCdevice *device) +{ UnlockUIntMapWrite(&device->BufferMap); } + inline struct ALbuffer *LookupBuffer(ALCdevice *device, ALuint id) -{ return (struct ALbuffer*)LookupUIntMapKey(&device->BufferMap, id); } +{ return (struct ALbuffer*)LookupUIntMapKeyNoLock(&device->BufferMap, id); } inline struct ALbuffer *RemoveBuffer(ALCdevice *device, ALuint id) -{ return (struct ALbuffer*)RemoveUIntMapKey(&device->BufferMap, id); } +{ return (struct ALbuffer*)RemoveUIntMapKeyNoLock(&device->BufferMap, id); } ALvoid ReleaseALBuffers(ALCdevice *device); diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index c5c9ea21..8e2c5cf2 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -36,6 +36,10 @@ #include "sample_cvt.h" +extern inline void LockBuffersRead(ALCdevice *device); +extern inline void UnlockBuffersRead(ALCdevice *device); +extern inline void LockBuffersWrite(ALCdevice *device); +extern inline void UnlockBuffersWrite(ALCdevice *device); extern inline struct ALbuffer *LookupBuffer(ALCdevice *device, ALuint id); extern inline struct ALbuffer *RemoveBuffer(ALCdevice *device, ALuint id); extern inline ALuint FrameSizeFromUserFmt(enum UserFmtChannels chans, enum UserFmtType type); @@ -85,10 +89,12 @@ AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers) context = GetContextRef(); if(!context) return; + device = context->Device; + + LockBuffersWrite(device); if(!(n >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - device = context->Device; for(i = 0;i < n;i++) { if(!buffers[i]) @@ -108,6 +114,7 @@ AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers) } done: + UnlockBuffersWrite(device); ALCcontext_DecRef(context); } @@ -119,8 +126,10 @@ AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer) context = GetContextRef(); if(!context) return AL_FALSE; + LockBuffersRead(context->Device); ret = ((!buffer || LookupBuffer(context->Device, buffer)) ? AL_TRUE : AL_FALSE); + UnlockBuffersRead(context->Device); ALCcontext_DecRef(context); @@ -144,6 +153,7 @@ AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoi if(!context) return; device = context->Device; + LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(!(size >= 0 && freq > 0)) @@ -272,6 +282,7 @@ AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoi } done: + UnlockBuffersRead(device); ALCcontext_DecRef(context); } @@ -291,6 +302,7 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, cons if(!context) return; device = context->Device; + LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(!(length >= 0 && offset >= 0)) @@ -351,6 +363,7 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, cons WriteUnlock(&albuf->lock); done: + UnlockBuffersRead(device); ALCcontext_DecRef(context); } @@ -369,6 +382,7 @@ AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, if(!context) return; device = context->Device; + LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(!(samples >= 0 && samplerate != 0)) @@ -388,6 +402,7 @@ AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, SET_ERROR_AND_GOTO(context, err, done); done: + UnlockBuffersRead(device); ALCcontext_DecRef(context); } @@ -404,6 +419,7 @@ AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, if(!context) return; device = context->Device; + LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(!(samples >= 0 && offset >= 0)) @@ -441,6 +457,7 @@ AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, WriteUnlock(&albuf->lock); done: + UnlockBuffersRead(device); ALCcontext_DecRef(context); } @@ -457,6 +474,7 @@ AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, if(!context) return; device = context->Device; + LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); if(!(samples >= 0 && offset >= 0)) @@ -494,6 +512,7 @@ AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, ReadUnlock(&albuf->lock); done: + UnlockBuffersRead(device); ALCcontext_DecRef(context); } @@ -524,6 +543,7 @@ AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat UNUSED(va if(!context) return; device = context->Device; + LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); @@ -534,6 +554,7 @@ AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat UNUSED(va } done: + UnlockBuffersRead(device); ALCcontext_DecRef(context); } @@ -547,6 +568,7 @@ AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat UNUSED(v if(!context) return; device = context->Device; + LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); @@ -557,6 +579,7 @@ AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat UNUSED(v } done: + UnlockBuffersRead(device); ALCcontext_DecRef(context); } @@ -570,6 +593,7 @@ AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *v if(!context) return; device = context->Device; + LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); @@ -582,6 +606,7 @@ AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *v } done: + UnlockBuffersRead(device); ALCcontext_DecRef(context); } @@ -596,6 +621,7 @@ AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value) if(!context) return; device = context->Device; + LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); @@ -618,6 +644,7 @@ AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value) } done: + UnlockBuffersRead(device); ALCcontext_DecRef(context); } @@ -666,6 +693,7 @@ AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *val if(!context) return; device = context->Device; + LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); @@ -697,6 +725,7 @@ AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *val } done: + UnlockBuffersRead(device); ALCcontext_DecRef(context); } @@ -711,6 +740,7 @@ AL_API ALvoid AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *val if(!context) return; device = context->Device; + LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); @@ -732,6 +762,7 @@ AL_API ALvoid AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *val } done: + UnlockBuffersRead(device); ALCcontext_DecRef(context); } @@ -745,6 +776,7 @@ AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *valu if(!context) return; device = context->Device; + LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); @@ -757,6 +789,7 @@ AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *valu } done: + UnlockBuffersRead(device); ALCcontext_DecRef(context); } @@ -777,6 +810,7 @@ AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *valu if(!context) return; device = context->Device; + LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); @@ -789,6 +823,7 @@ AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *valu } done: + UnlockBuffersRead(device); ALCcontext_DecRef(context); } @@ -803,6 +838,7 @@ AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value if(!context) return; device = context->Device; + LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); @@ -854,6 +890,7 @@ AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value } done: + UnlockBuffersRead(device); ALCcontext_DecRef(context); } @@ -867,6 +904,7 @@ AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1 if(!context) return; device = context->Device; + LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); @@ -879,6 +917,7 @@ AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1 } done: + UnlockBuffersRead(device); ALCcontext_DecRef(context); } @@ -908,6 +947,7 @@ AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values if(!context) return; device = context->Device; + LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); @@ -927,6 +967,7 @@ AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values } done: + UnlockBuffersRead(device); ALCcontext_DecRef(context); } diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index fc5d309b..8cab5ab3 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -636,12 +636,18 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_BUFFER: - CHECKVAL(*values == 0 || (buffer=LookupBuffer(device, *values)) != NULL); + LockBuffersRead(device); + if(!(*values == 0 || (buffer=LookupBuffer(device, *values)) != NULL)) + { + UnlockBuffersRead(device); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); + } WriteLock(&Source->queue_lock); if(!(Source->state == AL_STOPPED || Source->state == AL_INITIAL)) { WriteUnlock(&Source->queue_lock); + UnlockBuffersRead(device); SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); } @@ -670,6 +676,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p oldlist = ATOMIC_EXCHANGE(ALbufferlistitem*, &Source->queue, newlist); ATOMIC_STORE(&Source->current_buffer, newlist); WriteUnlock(&Source->queue_lock); + UnlockBuffersRead(device); /* Delete all elements in the previous queue */ while(oldlist != NULL) @@ -2388,6 +2395,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu BufferList = BufferList->next; } + LockBuffersRead(device); BufferListStart = NULL; BufferList = NULL; for(i = 0;i < nb;i++) @@ -2447,6 +2455,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu free(BufferListStart); BufferListStart = next; } + UnlockBuffersRead(device); goto done; } } @@ -2458,6 +2467,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu if(buffer) ReadUnlock(&buffer->lock); BufferList = BufferList->next; } + UnlockBuffersRead(device); /* Source is now streaming */ source->SourceType = AL_STREAMING; |