From 7a76f322eb0d834e64b2a3e98d756bf5dc40ccdf Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Fri, 30 Nov 2012 23:27:36 +0100 Subject: [PATCH] drain midi port output buffer before closing it ensuring the last few bytes are not lost --- sndiod/midi.c | 25 +++++++++++++++++++++---- sndiod/midi.h | 1 + sndiod/miofile.c | 2 ++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/sndiod/midi.c b/sndiod/midi.c index cb5af2c..c5c7953 100644 --- a/sndiod/midi.c +++ b/sndiod/midi.c @@ -519,7 +519,7 @@ port_unref(struct port *c) for (rxmask = 0, i = 0; i < MIDI_NEP; i++) rxmask |= midi_ep[i].txmask; if ((rxmask & c->midi->self) == 0 && c->state == PORT_INIT && !c->hold) - port_close(c); + port_drain(c); } struct port * @@ -572,6 +572,24 @@ port_close(struct port *c) return 1; } +void +port_drain(struct port *c) +{ + struct midi *ep = c->midi; + + if (!(ep->mode & MODE_MIDIOUT) || ep->obuf.used == 0) + port_close(c); + else { + c->state = PORT_DRAIN; +#ifdef DEBUG + if (log_level >= 3) { + port_log(c); + log_puts(": draining\n"); + } +#endif + } +} + int port_init(struct port *c) { @@ -583,7 +601,6 @@ port_init(struct port *c) void port_done(struct port *c) { - /* XXX: drain? */ - if (c->state != PORT_CFG) - port_close(c); + if (c->state == PORT_INIT) + port_drain(c); } diff --git a/sndiod/midi.h b/sndiod/midi.h index 719f772..c48a9b8 100644 --- a/sndiod/midi.h +++ b/sndiod/midi.h @@ -117,6 +117,7 @@ int port_ref(struct port *); void port_unref(struct port *); int port_init(struct port *); void port_done(struct port *); +void port_drain(struct port *); int port_close(struct port *); #endif /* !defined(MIDI_H) */ diff --git a/sndiod/miofile.c b/sndiod/miofile.c index 8530181..5b037f0 100644 --- a/sndiod/miofile.c +++ b/sndiod/miofile.c @@ -118,6 +118,8 @@ port_mio_out(void *arg) if (n < count) break; } + if (p->state == PORT_DRAIN && ep->obuf.used == 0) + port_close(p); midi_fill(ep); }