Drop blocks and instert silence immediately in the socket rx/tx code
authorratchov <ratchov@openbsd.org>
Tue, 31 Dec 2013 12:27:49 +0000 (12:27 +0000)
committerratchov <ratchov@openbsd.org>
Tue, 31 Dec 2013 12:27:49 +0000 (12:27 +0000)
path rather than waiting for the next device cycle. This fixes deadocks
when the slot uses the SIO_SYNC mode.

usr.bin/sndiod/dev.c

index 0fae549..6da914b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dev.c,v 1.8 2013/12/20 08:47:37 ratchov Exp $ */
+/*     $OpenBSD: dev.c,v 1.9 2013/12/31 12:27:49 ratchov Exp $ */
 /*
  * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org>
  *
@@ -1970,6 +1970,8 @@ slot_stop(struct slot *s)
 void
 slot_write(struct slot *s)
 {
+       int drop;
+
        if (s->pstate == SLOT_START && s->mix.buf.used == s->mix.buf.len) {
 #ifdef DEBUG
                if (log_level >= 4) {
@@ -1980,6 +1982,18 @@ slot_write(struct slot *s)
                s->pstate = SLOT_READY;
                slot_ready(s);
        }
+       drop = s->mix.drop;
+       slot_mix_drop(s);
+       while (drop > s->mix.drop) {
+#ifdef DEBUG
+               if (log_level >= 4) {
+                       slot_log(s);
+                       log_puts(": catching play block\n");
+               }
+#endif
+               s->ops->fill(s->arg);
+               drop--;
+       }
 }
 
 /*
@@ -1988,5 +2002,18 @@ slot_write(struct slot *s)
 void
 slot_read(struct slot *s)
 {
-       /* nothing yet */
+       int sil;
+
+       sil = s->sub.silence;
+       slot_sub_sil(s);
+       while (sil > s->sub.silence) {
+#ifdef DEBUG
+               if (log_level >= 4) {
+                       slot_log(s);
+                       log_puts(": catching rec block\n");
+               }
+#endif
+               s->ops->flush(s->arg);
+               sil--;
+       }
 }