mirror of
https://github.com/libretro/RetroArch.git
synced 2025-02-09 10:54:30 +00:00
(iOS, CoreAudio) Don't deadlock in coreaudio_write if the audio session is interrupted.
This commit is contained in:
parent
50cca385e6
commit
c9d968fa79
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user