aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/backends/qsa.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-02-18 17:32:07 -0800
committerChris Robinson <[email protected]>2017-02-18 17:32:07 -0800
commit247f56249ade334f8f7ef9eda9c380af0278562f (patch)
tree9c342e82e26e39bc7b075b62ca33ddd97969015f /Alc/backends/qsa.c
parent2448f88e70f6207ad5743f0a55eaa5de7cbce737 (diff)
Always lock the device backend before calling aluMixData
Diffstat (limited to 'Alc/backends/qsa.c')
-rw-r--r--Alc/backends/qsa.c89
1 files changed, 43 insertions, 46 deletions
diff --git a/Alc/backends/qsa.c b/Alc/backends/qsa.c
index b7923517..dabe5ee9 100644
--- a/Alc/backends/qsa.c
+++ b/Alc/backends/qsa.c
@@ -33,6 +33,8 @@
#include "alu.h"
#include "threads.h"
+#include "backends/base.h"
+
typedef struct {
snd_pcm_t* pcmHandle;
@@ -161,13 +163,13 @@ FORCE_ALIGN static int qsa_proc_playback(void* ptr)
{
ALCdevice* device=(ALCdevice*)ptr;
qsa_data* data=(qsa_data*)device->ExtraData;
- char* write_ptr;
- int avail;
snd_pcm_channel_status_t status;
struct sched_param param;
- fd_set wfds;
- int selectret;
struct timeval timeout;
+ char* write_ptr;
+ fd_set wfds;
+ ALint len;
+ int sret;
SetRTPriority();
althrd_setname(althrd_current(), MIXER_THREAD_NAME);
@@ -177,59 +179,53 @@ FORCE_ALIGN static int qsa_proc_playback(void* ptr)
param.sched_priority=param.sched_curpriority+1;
SchedSet(0, 0, SCHED_NOCHANGE, &param);
- ALint frame_size=FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
+ const ALint frame_size = FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
- while (!data->killNow)
+ V0(device->Backend,lock)();
+ while(!data->killNow)
{
- ALint len=data->size;
- write_ptr=data->buffer;
-
- avail=len/frame_size;
- aluMixData(device, write_ptr, avail);
+ FD_ZERO(&wfds);
+ FD_SET(data->audio_fd, &wfds);
+ timeout.tv_sec=2;
+ timeout.tv_usec=0;
- while (len>0 && !data->killNow)
+ /* Select also works like time slice to OS */
+ V0(device->Backend,unlock)();
+ sret = select(data->audio_fd+1, NULL, &wfds, NULL, &timeout);
+ V0(device->Backend,lock)();
+ if(sret == -1)
{
- FD_ZERO(&wfds);
- FD_SET(data->audio_fd, &wfds);
- timeout.tv_sec=2;
- timeout.tv_usec=0;
-
- /* Select also works like time slice to OS */
- selectret=select(data->audio_fd+1, NULL, &wfds, NULL, &timeout);
- switch (selectret)
- {
- case -1:
- aluHandleDisconnect(device);
- return 1;
- case 0:
- break;
- default:
- if (FD_ISSET(data->audio_fd, &wfds))
- {
- break;
- }
- break;
- }
-
- int wrote=snd_pcm_plugin_write(data->pcmHandle, write_ptr, len);
+ ERR("select error: %s\n", strerror(errno));
+ aluHandleDisconnect(device);
+ break;
+ }
+ if(sret == 0)
+ {
+ ERR("select timeout\n");
+ continue;
+ }
- if (wrote<=0)
+ len = data->size;
+ write_ptr = data->buffer;
+ aluMixData(device, write_ptr, len/frame_size);
+ while(len>0 && !data->killNow)
+ {
+ int wrote = snd_pcm_plugin_write(data->pcmHandle, write_ptr, len);
+ if(wrote <= 0)
{
- if ((errno==EAGAIN) || (errno==EWOULDBLOCK))
- {
+ if(errno==EAGAIN || errno==EWOULDBLOCK)
continue;
- }
- memset(&status, 0, sizeof (status));
- status.channel=SND_PCM_CHANNEL_PLAYBACK;
+ memset(&status, 0, sizeof(status));
+ status.channel = SND_PCM_CHANNEL_PLAYBACK;
snd_pcm_plugin_status(data->pcmHandle, &status);
/* we need to reinitialize the sound channel if we've underrun the buffer */
- if ((status.status==SND_PCM_STATUS_UNDERRUN) ||
- (status.status==SND_PCM_STATUS_READY))
+ if(status.status == SND_PCM_STATUS_UNDERRUN ||
+ status.status == SND_PCM_STATUS_READY)
{
- if ((snd_pcm_plugin_prepare(data->pcmHandle, SND_PCM_CHANNEL_PLAYBACK))<0)
+ if(snd_pcm_plugin_prepare(data->pcmHandle, SND_PCM_CHANNEL_PLAYBACK) < 0)
{
aluHandleDisconnect(device);
break;
@@ -238,11 +234,12 @@ FORCE_ALIGN static int qsa_proc_playback(void* ptr)
}
else
{
- write_ptr+=wrote;
- len-=wrote;
+ write_ptr += wrote;
+ len -= wrote;
}
}
}
+ V0(device->Backend,unlock)();
return 0;
}