aboutsummaryrefslogtreecommitdiff
path: root/src/pcm_hw.c
diff options
context:
space:
mode:
authorSimon Wilson <simonrules@users.noreply.github.com>2021-06-02 09:22:23 -0600
committerGitHub <noreply@github.com>2021-06-02 09:22:23 -0600
commit496e653335d27557bbd1f795b1eacd2948ab192a (patch)
tree7cf42df6c5c17b207be376eb00fe91d42bd9e352 /src/pcm_hw.c
parent36f9078ef5410279725207daa00943ee48b05253 (diff)
parentea4546b237269915e832fd74a9883a2dadf46093 (diff)
Merge pull request #208 from dvdli/tinyalsa-pcm-open-blocked
force pcm_open to open device with the non-blocking flag
Diffstat (limited to 'src/pcm_hw.c')
-rw-r--r--src/pcm_hw.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/src/pcm_hw.c b/src/pcm_hw.c
index 38b2e83..4792895 100644
--- a/src/pcm_hw.c
+++ b/src/pcm_hw.c
@@ -111,16 +111,25 @@ static int pcm_hw_open(unsigned int card, unsigned int device,
snprintf(fn, sizeof(fn), "/dev/snd/pcmC%uD%u%c", card, device,
flags & PCM_IN ? 'c' : 'p');
- if (flags & PCM_NONBLOCK)
- fd = open(fn, O_RDWR|O_NONBLOCK);
- else
- fd = open(fn, O_RDWR);
+ // Open the device with non-blocking flag to avoid to be blocked in kernel when all of the
+ // substreams of this PCM device are opened by others.
+ fd = open(fn, O_RDWR | O_NONBLOCK);
if (fd < 0) {
free(hw_data);
return fd;
}
+ if ((flags & PCM_NONBLOCK) == 0) {
+ // Set the file descriptor to blocking mode.
+ if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK) < 0) {
+ fprintf(stderr, "failed to set to blocking mode on %s", fn);
+ close(fd);
+ free(hw_data);
+ return -ENODEV;
+ }
+ }
+
hw_data->card = card;
hw_data->device = device;
hw_data->fd = fd;