(iOS, CoreAudio) Don't deadlock in coreaudio_write if the audio session is interrupted.

This commit is contained in:
meancoot 2013-09-25 11:56:02 -04:00
parent 50cca385e6
commit c9d968fa79

View File

@ -24,6 +24,8 @@
#ifdef OSX
#include <CoreAudio/CoreAudio.h>
#else
#include <AudioToolbox/AudioToolbox.h>
#endif
#include <CoreAudio/CoreAudioTypes.h>
@ -43,6 +45,8 @@ typedef struct coreaudio
size_t buffer_size;
} coreaudio_t;
static bool g_interrupted;
static void coreaudio_free(void *data)
{
coreaudio_t *dev = (coreaudio_t*)data;
@ -139,6 +143,14 @@ done:
}
#endif
#ifdef IOS
static void coreaudio_interrupt_listener(void *data, UInt32 interrupt_state)
{
(void)data;
g_interrupted = (interrupt_state == kAudioSessionBeginInterruption);
}
#endif
static void *coreaudio_init(const char *device, unsigned rate, unsigned latency)
{
(void)device;
@ -150,6 +162,16 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency)
pthread_mutex_init(&dev->lock, NULL);
pthread_cond_init(&dev->cond, NULL);
#ifdef IOS
static bool session_initialized = false;
if (!session_initialized)
{
session_initialized = true;
AudioSessionInitialize(0, 0, coreaudio_interrupt_listener, 0);
AudioSessionSetActive(true);
}
#endif
// Create AudioComponent
AudioComponentDescription desc = {0};
desc.componentType = kAudioUnitType_Output;
@ -261,7 +283,17 @@ static ssize_t coreaudio_write(void *data, const void *buf_, size_t size)
const uint8_t *buf = (const uint8_t*)buf_;
size_t written = 0;
while (size > 0)
#ifdef IOS
struct timeval time;
gettimeofday(&time, 0);
struct timespec timeout;
memset(&timeout, 0, sizeof(timeout));
timeout.tv_sec = time.tv_sec + 3;
timeout.tv_nsec = time.tv_usec * 1000;
#endif
while (!g_interrupted && size > 0)
{
pthread_mutex_lock(&dev->lock);
@ -280,8 +312,13 @@ static ssize_t coreaudio_write(void *data, const void *buf_, size_t size)
break;
}
#ifdef IOS
if (write_avail == 0 && pthread_cond_timedwait(&dev->cond, &dev->lock, &timeout) == ETIMEDOUT)
g_interrupted = true;
#else
if (write_avail == 0)
pthread_cond_wait(&dev->cond, &dev->lock);
#endif
pthread_mutex_unlock(&dev->lock);
}