alsasink: Allow stop() function to happen during failing writes
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Tue, 24 Aug 2021 19:27:32 +0000 (15:27 -0400)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Mon, 20 Sep 2021 18:06:44 +0000 (18:06 +0000)
In ALSA, there is possible temporary failures that may require a retry,
though in certain situation, this may leak to the write() function
holding on a lock forever preventing the pipeline from going to pause
or stop. Fix this by shortly dropping the lock between retries.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1261>

ext/alsa/gstalsasink.c

index 6d72788..eab4059 100644 (file)
@@ -1075,12 +1075,18 @@ gst_alsasink_write (GstAudioSink * asink, gpointer data, guint length)
     if (err < 0) {
       GST_DEBUG_OBJECT (asink, "Write error: %s (%d)", snd_strerror (err), err);
       if (err == -EAGAIN) {
-        continue;
+        /* will continue out of the if/else group */
       } else if (err == -ENODEV) {
         goto device_disappeared;
       } else if (xrun_recovery (alsa, alsa->handle, err) < 0) {
         goto write_error;
       }
+
+      /* Unlock so that _reset() can run and break an otherwise infinit loop
+       * here */
+      GST_ALSA_SINK_UNLOCK (asink);
+      g_thread_yield ();
+      GST_ALSA_SINK_LOCK (asink);
       continue;
     } else if (err == 0 && alsa->hw_support_pause) {
       /* We might be already paused, if so, just bail */