aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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;