Add retries for pcm_read and pcm_write

Bug: 238957114
Test: boot emulator, check if audio works
Signed-off-by: Roman Kiryanov <rkir@google.com>
Change-Id: I63c0fd407b411ab7958347d10175873cf78b40ab
diff --git a/audio/talsa.cpp b/audio/talsa.cpp
index 783e97d..4c2d7f8 100644
--- a/audio/talsa.cpp
+++ b/audio/talsa.cpp
@@ -188,13 +188,26 @@
         return FAILURE(false);
     }
 
-    const int r = ::pcm_read(pcm, data, count);
-    if (r) {
-        ALOGE("%s:%d pcm_read failed with %s (%d)",
-              __func__, __LINE__, ::pcm_get_error(pcm), r);
-        return FAILURE(false);
-    } else {
-        return true;
+    int tries = 3;
+    while (true) {
+        --tries;
+        const int r = ::pcm_read(pcm, data, count);
+        switch (-r) {
+        case 0:
+            return true;
+
+        case EIO:
+        case EAGAIN:
+            if (tries > 0) {
+                break;
+            }
+            [[fallthrough]];
+
+        default:
+            ALOGW("%s:%d pcm_read failed with '%s' (%d)",
+                  __func__, __LINE__, ::pcm_get_error(pcm), r);
+            return FAILURE(false);
+        }
     }
 }
 
@@ -203,13 +216,26 @@
         return FAILURE(false);
     }
 
-    const int r = ::pcm_write(pcm, data, count);
-    if (r) {
-        ALOGE("%s:%d pcm_write failed with %s (%d)",
-              __func__, __LINE__, ::pcm_get_error(pcm), r);
-        return FAILURE(false);
-    } else {
-        return true;
+    int tries = 3;
+    while (true) {
+        --tries;
+        const int r = ::pcm_write(pcm, data, count);
+        switch (-r) {
+        case 0:
+            return true;
+
+        case EIO:
+        case EAGAIN:
+            if (tries > 0) {
+                break;
+            }
+            [[fallthrough]];
+
+        default:
+            ALOGW("%s:%d pcm_write failed with '%s' (%d)",
+                  __func__, __LINE__, ::pcm_get_error(pcm), r);
+            return FAILURE(false);
+        }
     }
 }