File jack2-PR_435-484_merged.patch of Package jack

diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp
index 62d9f43..06be2dc 100644
--- a/linux/alsa/JackAlsaDriver.cpp
+++ b/linux/alsa/JackAlsaDriver.cpp
@@ -406,6 +406,7 @@ int JackAlsaDriver::Read()
     int wait_status;
     jack_nframes_t nframes;
     fDelayedUsecs = 0.f;
+    int retry_cnt = 0;
 
 retry:
 
@@ -420,6 +421,11 @@ retry:
          */
         jack_log("ALSA XRun wait_status = %d", wait_status);
         NotifyXRun(fBeginDateUst, fDelayedUsecs);
+        if(retry_cnt >= MAX_RECOVERY_RETRY) {
+            jack_error("ALSA Device not recovering, tried Xrun recovery for %d times", retry_cnt);
+            return -1;
+        }
+        retry_cnt++;
         goto retry; /* recoverable error*/
     }
 
@@ -920,10 +926,14 @@ void SetTime(jack_time_t time)
     g_alsa_driver->SetTimetAux(time);
 }
 
-int Restart()
+int Restart(int delay)
 {
     int res;
+
     if ((res = g_alsa_driver->Stop()) == 0) {
+        if(delay > 0) {
+            usleep(delay * MS_TO_US);
+        }
         res = g_alsa_driver->Start();
     }
     return res;
diff --git a/linux/alsa/JackAlsaDriver.h b/linux/alsa/JackAlsaDriver.h
index c62ff54..afc0a3f 100644
--- a/linux/alsa/JackAlsaDriver.h
+++ b/linux/alsa/JackAlsaDriver.h
@@ -26,6 +26,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 #include "JackTime.h"
 #include "alsa_driver.h"
 
+/* Milli Seconds represented in Micro seconds */
+#define MS_TO_US   1000
+/* Max re-try count for Alsa XRUNs */
+#define MAX_RECOVERY_RETRY 10
+
 namespace Jack
 {
 
diff --git a/linux/alsa/alsa_driver.c b/linux/alsa/alsa_driver.c
index 9573001..d9da869 100644
--- a/linux/alsa/alsa_driver.c
+++ b/linux/alsa/alsa_driver.c
@@ -58,6 +58,10 @@ char* strcasestr(const char* haystack, const char* needle);
 #define XRUN_REPORT_DELAY 0
 /* Max re-try count for Alsa poll timeout handling */
 #define MAX_RETRY_COUNT 5
+/* Max re-try count for Alsa poll timeout handling */
+#define MAX_RETRY_COUNT 5
+/* Delay in initiating the second xrun recovery */
+#define RECOVER_DELAY_MS 20
 
 void
 jack_driver_init (jack_driver_t *driver)
@@ -1168,7 +1172,7 @@ alsa_driver_stop (alsa_driver_t *driver)
 }
 
 static int
-alsa_driver_restart (alsa_driver_t *driver)
+alsa_driver_restart (alsa_driver_t *driver, int delay)
 {
 	int res;
 
@@ -1178,7 +1182,7 @@ alsa_driver_restart (alsa_driver_t *driver)
  	if ((res = driver->nt_stop((struct _jack_driver_nt *) driver))==0)
 		res = driver->nt_start((struct _jack_driver_nt *) driver);
     */
-    res = Restart();
+    res = Restart(delay);
 	driver->xrun_recovery = 0;
 
 	if (res && driver->midi)
@@ -1192,6 +1196,7 @@ alsa_driver_xrun_recovery (alsa_driver_t *driver, float *delayed_usecs)
 {
 	snd_pcm_status_t *status;
 	int res;
+	int delay = 0;
 
 	snd_pcm_status_alloca(&status);
 
@@ -1224,10 +1229,11 @@ alsa_driver_xrun_recovery (alsa_driver_t *driver, float *delayed_usecs)
 		}
 	}
 
+	driver->xrun_count++;
+
 	if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN
 	    && driver->process_count > XRUN_REPORT_DELAY) {
 		struct timeval now, diff, tstamp;
-		driver->xrun_count++;
 		snd_pcm_status_get_tstamp(status,&now);
 		snd_pcm_status_get_trigger_tstamp(status, &tstamp);
 		timersub(&now, &tstamp, &diff);
@@ -1247,7 +1253,12 @@ alsa_driver_xrun_recovery (alsa_driver_t *driver, float *delayed_usecs)
 		}
 	}
 
-	if (alsa_driver_restart (driver)) {
+	/* Try the first xrun recovery without delay and the subsequent ones with delay */
+	if(driver->xrun_count > 1) {
+		delay = RECOVER_DELAY_MS;
+	}
+
+	if (alsa_driver_restart (driver, delay)) {
 		return -1;
 	}
 	return 0;
@@ -1277,6 +1288,7 @@ alsa_driver_set_clock_sync_status (alsa_driver_t *driver, channel_t chn,
 				   ClockSyncStatus status)
 {
 	driver->clock_sync_data[chn] = status;
+	int retry_cnt = 0;
 	alsa_driver_clock_sync_notify (driver, chn, status);
 }
 
@@ -1536,6 +1548,10 @@ alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float
 	if (xrun_detected) {
 		*status = alsa_driver_xrun_recovery (driver, delayed_usecs);
 		return 0;
+	} else {
+		if(driver->xrun_count > 0) {
+			driver->xrun_count = 0;
+		}
 	}
 
 	*status = 0;
diff --git a/linux/alsa/alsa_driver.h b/linux/alsa/alsa_driver.h
index efe93de..36a0d01 100644
--- a/linux/alsa/alsa_driver.h
+++ b/linux/alsa/alsa_driver.h
@@ -278,7 +278,7 @@ void MonitorInput();
 void ClearOutput();
 void WriteOutput(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nwritten);
 void SetTime(jack_time_t time);
-int Restart();
+int Restart(int delay);
 
 #ifdef __cplusplus
 }
openSUSE Build Service is sponsored by