]> git.alsa-project.org Git - alsa-utils.git/commitdiff
axfer: handle -ETIMEDOUT before handle mmap I/O operation
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Tue, 29 Oct 2019 15:14:14 +0000 (00:14 +0900)
committerJaroslav Kysela <perex@perex.cz>
Wed, 30 Oct 2019 12:13:22 +0000 (13:13 +0100)
When running for IRQ-based scheduling model, transmission backend is
expected to queue PCM event in different context from the main thread.
When queueing no events during time equivalent to one period of PCM
buffer, the backend has problems.

This commit outputs report it for mmap operation for IRQ-based
scheduling model. The timeout is equivalent to all frames in buffer,
instead of period for safe.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
axfer/xfer-libasound-irq-mmap.c

index 71ee79f81b64d9c10c38001b4f0b59ce69a3da6c..a13b3c3003541bf9f6f46e4ced74c39daadc1460 100644 (file)
@@ -82,10 +82,28 @@ static int irq_mmap_process_frames(struct libasound_state *state,
        int err;
 
        if (state->use_waiter) {
+               unsigned int msec_per_buffer;
                unsigned short revents;
 
+               // Wait during msec equivalent to all audio data frames in
+               // buffer instead of period, for safe.
+               err = snd_pcm_hw_params_get_buffer_time(state->hw_params,
+                                                       &msec_per_buffer, NULL);
+               if (err < 0)
+                       return err;
+               msec_per_buffer /= 1000;
+
                // Wait for hardware IRQ when no avail space in buffer.
-               err = xfer_libasound_wait_event(state, -1, &revents);
+               err = xfer_libasound_wait_event(state, msec_per_buffer,
+                                               &revents);
+               if (err == -ETIMEDOUT) {
+                       logging(state,
+                               "No event occurs for PCM substream during %u "
+                               "msec. The implementaion of kernel driver or "
+                               "userland backend causes this issue.\n",
+                               msec_per_buffer);
+                       return err;
+               }
                if (err < 0)
                        return err;
                if (revents & POLLERR) {