mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-18 16:30:29 +00:00
Fixed potential deadlock, if a delegate decided to dealloc the queue as a result of its prompting.
This commit is contained in:
parent
bce5abd33b
commit
38ce4dc56c
@ -23,10 +23,11 @@ static NSLock *CSAudioQueueDeallocLock;
|
|||||||
|
|
||||||
#pragma mark - AudioQueue callbacks
|
#pragma mark - AudioQueue callbacks
|
||||||
|
|
||||||
- (void)audioQueue:(AudioQueueRef)theAudioQueue didCallbackWithBuffer:(AudioQueueBufferRef)buffer
|
/*!
|
||||||
|
@returns @c YES if the queue is running dry; @c NO otherwise.
|
||||||
|
*/
|
||||||
|
- (BOOL)audioQueue:(AudioQueueRef)theAudioQueue didCallbackWithBuffer:(AudioQueueBufferRef)buffer
|
||||||
{
|
{
|
||||||
[self.delegate audioQueueIsRunningDry:self];
|
|
||||||
|
|
||||||
[_storedBuffersLock lock];
|
[_storedBuffersLock lock];
|
||||||
for(int c = 0; c < NumberOfStoredAudioQueueBuffer; c++)
|
for(int c = 0; c < NumberOfStoredAudioQueueBuffer; c++)
|
||||||
{
|
{
|
||||||
@ -35,11 +36,12 @@ static NSLock *CSAudioQueueDeallocLock;
|
|||||||
if(_storedBuffers[c]) AudioQueueFreeBuffer(_audioQueue, _storedBuffers[c]);
|
if(_storedBuffers[c]) AudioQueueFreeBuffer(_audioQueue, _storedBuffers[c]);
|
||||||
_storedBuffers[c] = buffer;
|
_storedBuffers[c] = buffer;
|
||||||
[_storedBuffersLock unlock];
|
[_storedBuffersLock unlock];
|
||||||
return;
|
return YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[_storedBuffersLock unlock];
|
[_storedBuffersLock unlock];
|
||||||
AudioQueueFreeBuffer(_audioQueue, buffer);
|
AudioQueueFreeBuffer(_audioQueue, buffer);
|
||||||
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void audioOutputCallback(
|
static void audioOutputCallback(
|
||||||
@ -47,11 +49,16 @@ static void audioOutputCallback(
|
|||||||
AudioQueueRef inAQ,
|
AudioQueueRef inAQ,
|
||||||
AudioQueueBufferRef inBuffer)
|
AudioQueueBufferRef inBuffer)
|
||||||
{
|
{
|
||||||
|
// Pull the delegate call for audio queue running dry outside of the locked region, to allow non-deadlocking
|
||||||
|
// lifecycle -dealloc events to result from it.
|
||||||
|
CSAudioQueue *queue = (__bridge CSAudioQueue *)inUserData;
|
||||||
|
BOOL isRunningDry = NO;
|
||||||
if([CSAudioQueueDeallocLock tryLock])
|
if([CSAudioQueueDeallocLock tryLock])
|
||||||
{
|
{
|
||||||
[(__bridge CSAudioQueue *)inUserData audioQueue:inAQ didCallbackWithBuffer:inBuffer];
|
isRunningDry = [queue audioQueue:inAQ didCallbackWithBuffer:inBuffer];
|
||||||
[CSAudioQueueDeallocLock unlock];
|
[CSAudioQueueDeallocLock unlock];
|
||||||
}
|
}
|
||||||
|
if(isRunningDry) [queue.delegate audioQueueIsRunningDry:queue];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Standard object lifecycle
|
#pragma mark - Standard object lifecycle
|
||||||
|
Loading…
x
Reference in New Issue
Block a user