summaryrefslogtreecommitdiffstats
path: root/audio/pcm_bluetooth.c
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2007-09-05 21:25:25 +0000
committerLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2007-09-05 21:25:25 +0000
commite4b3ec84ce3680ca33ae88b76e1ce138756c0427 (patch)
tree83a318044776a88be6e7dbf688e41db2eeebb958 /audio/pcm_bluetooth.c
parentc4e21c814832ea94f64821a2360a28074d03be1a (diff)
Use poll instead of usleep to wait on worker thread.
Diffstat (limited to 'audio/pcm_bluetooth.c')
-rw-r--r--audio/pcm_bluetooth.c81
1 files changed, 51 insertions, 30 deletions
diff --git a/audio/pcm_bluetooth.c b/audio/pcm_bluetooth.c
index da5927d0..9e5058c0 100644
--- a/audio/pcm_bluetooth.c
+++ b/audio/pcm_bluetooth.c
@@ -43,7 +43,7 @@
#define UINT_SECS_MAX (UINT_MAX / 1000000 - 1)
-#define MIN_PERIOD_TIME 1000
+#define MIN_PERIOD_TIME 1
#define BUFFER_SIZE 2048
@@ -135,8 +135,8 @@ struct bluetooth_data {
snd_pcm_ioplug_t io;
volatile snd_pcm_sframes_t hw_ptr;
struct ipc_data_cfg cfg; /* Bluetooth device config */
- int stream_fd; /* Audio stream filedescriptor */
- int sock; /* Daemon unix socket */
+ struct pollfd stream; /* Audio stream filedescriptor */
+ struct pollfd server; /* Audio daemon filedescriptor */
uint8_t buffer[BUFFER_SIZE]; /* Encoded transfer buffer */
int count; /* Transfer buffer counter */
struct bluetooth_a2dp a2dp; /* A2DP data */
@@ -166,6 +166,10 @@ static void *playback_hw_thread(void *param)
unsigned int prev_periods;
double period_time;
struct timeval start;
+ struct pollfd fds[2];
+
+ fds[0] = data->server;
+ fds[1] = data->stream;
prev_periods = 0;
period_time = 1000000.0 * data->io.period_size / data->io.rate;
@@ -175,6 +179,7 @@ static void *playback_hw_thread(void *param)
while (1) {
unsigned int dtime, periods;
struct timeval cur, delta;
+ int ret;
if (data->stopped)
goto iter_sleep;
@@ -208,11 +213,26 @@ static void *playback_hw_thread(void *param)
}
iter_sleep:
- usleep(MIN_PERIOD_TIME);
+ ret = poll(fds, 2, MIN_PERIOD_TIME);
+ if (ret < 0) {
+ SNDERR("poll error: %s (%d)", strerror(errno), errno);
+ if (errno != EINTR)
+ break;
+ } else if (ret > 0) {
+ ret = (fds[0].revents) ? 0 : 1;
+ SNDERR("poll fd %d revents %d", ret, fds[ret].revents);
+ if (fds[ret].revents & POLLERR ||
+ fds[ret].revents & POLLHUP ||
+ fds[ret].revents & POLLNVAL)
+ break;
+ }
/* Offer opportunity to be canceled by main thread */
pthread_testcancel();
}
+
+ data->hw_thread = 0;
+ pthread_exit(NULL);
}
static int bluetooth_state_init(struct ipc_packet *pkt, int newstate)
@@ -240,7 +260,7 @@ static int bluetooth_state(struct bluetooth_data *data, int newstate)
if (ret < 0)
return -ret;
- ret = send(data->sock, pkt, sizeof(*pkt) + pkt->length, 0);
+ ret = send(data->server.fd, pkt, sizeof(*pkt) + pkt->length, 0);
if (ret < 0)
return -errno;
else if (ret == 0)
@@ -250,7 +270,7 @@ static int bluetooth_state(struct bluetooth_data *data, int newstate)
memset(buf, 0, sizeof(buf));
- ret = recv(data->sock, buf, sizeof(*pkt) + sizeof(*state), 0);
+ ret = recv(data->server.fd, buf, sizeof(*pkt) + sizeof(*state), 0);
if (ret < 0)
return -errno;
else if (ret == 0)
@@ -314,11 +334,11 @@ static void bluetooth_exit(struct bluetooth_data *data)
{
struct bluetooth_a2dp *a2dp = &data->a2dp;
- if (data->sock >= 0)
- close(data->sock);
+ if (data->server.fd >= 0)
+ close(data->server.fd);
- if (data->stream_fd >= 0)
- close(data->stream_fd);
+ if (data->stream.fd >= 0)
+ close(data->stream.fd);
if (data->hw_thread) {
pthread_cancel(data->hw_thread);
@@ -376,19 +396,19 @@ static int bluetooth_hsp_hw_params(snd_pcm_ioplug_t *io,
uint32_t period_count = io->buffer_size / io->period_size;
int opt_name, err;
- DBG("fd=%d period_count=%d", data->stream_fd, period_count);
+ DBG("fd=%d period_count=%d", data->stream.fd, period_count);
opt_name = (io->stream == SND_PCM_STREAM_PLAYBACK) ?
SCO_TXBUFS : SCO_RXBUFS;
- if (setsockopt(data->stream_fd, SOL_SCO, opt_name, &period_count,
+ if (setsockopt(data->stream.fd, SOL_SCO, opt_name, &period_count,
sizeof(period_count)) == 0)
return 0;
opt_name = (io->stream == SND_PCM_STREAM_PLAYBACK) ?
SO_SNDBUF : SO_RCVBUF;
- if (setsockopt(data->stream_fd, SOL_SCO, opt_name, &period_count,
+ if (setsockopt(data->stream.fd, SOL_SCO, opt_name, &period_count,
sizeof(period_count)) == 0)
return 0;
@@ -408,12 +428,12 @@ static int bluetooth_a2dp_hw_params(snd_pcm_ioplug_t *io,
int opt_name, err;
struct timeval t = { 0, period_count };
- DBG("fd=%d period_count=%d", data->stream_fd, period_count);
+ DBG("fd=%d period_count=%d", data->stream.fd, period_count);
opt_name = (io->stream == SND_PCM_STREAM_PLAYBACK) ?
SO_SNDTIMEO : SO_RCVTIMEO;
- if (setsockopt(data->stream_fd, SOL_SOCKET, opt_name, &t,
+ if (setsockopt(data->stream.fd, SOL_SOCKET, opt_name, &t,
sizeof(t)) == 0)
return 0;
@@ -434,7 +454,7 @@ static int bluetooth_poll_descriptors(snd_pcm_ioplug_t *io,
if (space < 1)
return 0;
- pfd[0].fd = data->stream_fd;
+ pfd[0].fd = data->stream.fd;
pfd[0].events = POLLIN;
pfd[0].revents = 0;
@@ -512,7 +532,7 @@ static snd_pcm_sframes_t bluetooth_hsp_read(snd_pcm_ioplug_t *io,
frame_size = areas->step / 8;
- nrecv = recv(data->stream_fd, data->buffer, cfg.pkt_len,
+ nrecv = recv(data->stream.fd, data->buffer, cfg.pkt_len,
MSG_WAITALL | (io->nonblock ? MSG_DONTWAIT : 0));
if (nrecv < 0) {
@@ -592,7 +612,7 @@ static snd_pcm_sframes_t bluetooth_hsp_write(snd_pcm_ioplug_t *io,
goto done;
}
- rsend = send(data->stream_fd, data->buffer, cfg.pkt_len,
+ rsend = send(data->stream.fd, data->buffer, cfg.pkt_len,
io->nonblock ? MSG_DONTWAIT : 0);
if (rsend > 0) {
/* Reset count pointer */
@@ -636,7 +656,7 @@ static int avdtp_write(struct bluetooth_data *data)
header->timestamp = htonl(a2dp->nsamples);
header->ssrc = htonl(1);
- ret = send(data->stream_fd, a2dp->buffer, a2dp->count, MSG_DONTWAIT);
+ ret = send(data->stream.fd, a2dp->buffer, a2dp->count, MSG_DONTWAIT);
if (ret == -1)
ret = -errno;
@@ -919,7 +939,7 @@ static int bluetooth_recvmsg_fd(struct bluetooth_data *data)
msgh.msg_control = &cmsg_b;
msgh.msg_controllen = CMSG_LEN(sizeof(int));
- ret = recvmsg(data->sock, &msgh, 0);
+ ret = recvmsg(data->server.fd, &msgh, 0);
if (ret < 0) {
err = errno;
SNDERR("Unable to receive fd: %s (%d)", strerror(err), err);
@@ -931,8 +951,8 @@ static int bluetooth_recvmsg_fd(struct bluetooth_data *data)
cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
if (cmsg->cmsg_level == SOL_SOCKET
&& cmsg->cmsg_type == SCM_RIGHTS) {
- data->stream_fd = (*(int *) CMSG_DATA(cmsg));
- DBG("stream_fd=%d", data->stream_fd);
+ data->stream.fd = (*(int *) CMSG_DATA(cmsg));
+ DBG("stream_fd=%d", data->stream.fd);
return 0;
}
}
@@ -1132,7 +1152,7 @@ static int bluetooth_cfg(struct bluetooth_data *data, snd_pcm_stream_t stream,
if (ret < 0)
return -ret;
- ret = send(data->sock, pkt, sizeof(*pkt) + pkt->length, 0);
+ ret = send(data->server.fd, pkt, sizeof(*pkt) + pkt->length, 0);
if (ret < 0)
return -errno;
else if (ret == 0)
@@ -1142,7 +1162,7 @@ static int bluetooth_cfg(struct bluetooth_data *data, snd_pcm_stream_t stream,
memset(buf, 0, sizeof(buf));
- ret = recv(data->sock, buf, sizeof(*pkt) + sizeof(*cfg), 0);
+ ret = recv(data->server.fd, buf, sizeof(*pkt) + sizeof(*cfg), 0);
if (ret < 0)
return -errno;
else if (ret == 0)
@@ -1163,7 +1183,7 @@ static int bluetooth_cfg(struct bluetooth_data *data, snd_pcm_stream_t stream,
if (cfg->codec != CFG_CODEC_SBC)
goto done;
- ret = recv(data->sock, sbc, sizeof(*sbc), 0);
+ ret = recv(data->server.fd, sbc, sizeof(*sbc), 0);
if (ret < 0)
return -errno;
else if (ret == 0)
@@ -1184,7 +1204,7 @@ done:
DBG("Device configuration:");
DBG("\n\tfd=%d\n\tfd_opt=%u\n\tpkt_len=%u\n\tsample_size=%u\n\trate=%u",
- data->stream_fd, data->cfg.fd_opt, data->cfg.pkt_len,
+ data->stream.fd, data->cfg.fd_opt, data->cfg.pkt_len,
data->cfg.sample_size, data->cfg.rate);
if (data->cfg.codec == CFG_CODEC_SBC) {
@@ -1193,7 +1213,7 @@ done:
return ret;
}
- if (data->stream_fd == -1) {
+ if (data->stream.fd == -1) {
SNDERR("Error while configuring device: could not acquire audio socket");
return -EINVAL;
}
@@ -1204,7 +1224,7 @@ done:
/* It is possible there is some outstanding
data in the pipe - we have to empty it */
- while (recv(data->stream_fd, data->buffer, data->cfg.pkt_len,
+ while (recv(data->stream.fd, data->buffer, data->cfg.pkt_len,
MSG_DONTWAIT) > 0);
memset(data->buffer, 0, sizeof(data->buffer));
@@ -1225,7 +1245,7 @@ static int bluetooth_init(struct bluetooth_data *data, snd_pcm_stream_t stream,
memset(data, 0, sizeof(struct bluetooth_data));
- data->sock = -1;
+ data->server.fd = -1;
sk = socket(PF_LOCAL, SOCK_STREAM, 0);
if (sk < 0) {
@@ -1242,7 +1262,8 @@ static int bluetooth_init(struct bluetooth_data *data, snd_pcm_stream_t stream,
return -err;
}
- data->sock = sk;
+ data->server.fd = sk;
+ data->server.events = POLLIN;
data->pipefd[0] = -1;
data->pipefd[1] = -1;