diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2012-11-02 10:24:59 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2012-11-02 10:24:59 +0000 |
commit | fb533b779e3fecc5418fedc3e2d127f9e7e6390b (patch) | |
tree | e790143bd322e795e85b9deb8fe4230d5f48169f /lib/libsndio | |
parent | 36253b58cd4016fae96da73b8bb08cdb8fe98a07 (diff) |
Use dedicated messages for flow control instead of abusing clock tick
messages and enable flow control for MIDI. Since this requires protocol
version bump, both sndiod and libsndio must be kept up to date to work
together.
Diffstat (limited to 'lib/libsndio')
-rw-r--r-- | lib/libsndio/amsg.h | 6 | ||||
-rw-r--r-- | lib/libsndio/aucat.c | 3 | ||||
-rw-r--r-- | lib/libsndio/aucat.h | 1 | ||||
-rw-r--r-- | lib/libsndio/mio_aucat.c | 52 | ||||
-rw-r--r-- | lib/libsndio/sio_aucat.c | 39 |
5 files changed, 69 insertions, 32 deletions
diff --git a/lib/libsndio/amsg.h b/lib/libsndio/amsg.h index 585b1be8ce2..6a5664ea138 100644 --- a/lib/libsndio/amsg.h +++ b/lib/libsndio/amsg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: amsg.h,v 1.4 2011/11/15 08:05:22 ratchov Exp $ */ +/* $OpenBSD: amsg.h,v 1.5 2012/11/02 10:24:58 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -42,7 +42,7 @@ struct amsg { #define AMSG_START 3 /* request the server to start the stream */ #define AMSG_STOP 4 /* request the server to stop the stream */ #define AMSG_DATA 5 /* data block */ -#define AMSG_POS 6 /* initial position */ +#define AMSG_FLOWCTL 6 /* feedback about buffer usage */ #define AMSG_MOVE 7 /* position changed */ #define AMSG_SETVOL 9 /* set volume */ #define AMSG_HELLO 10 /* say hello, check versions and so ... */ @@ -80,7 +80,7 @@ struct amsg { } vol; struct amsg_hello { uint16_t mode; /* bitmap of MODE_XXX */ -#define AMSG_VERSION 5 +#define AMSG_VERSION 6 uint8_t version; /* protocol version */ uint8_t devnum; /* device number */ uint32_t _reserved[1]; /* for future use */ diff --git a/lib/libsndio/aucat.c b/lib/libsndio/aucat.c index f155c892568..e1e5211a3ea 100644 --- a/lib/libsndio/aucat.c +++ b/lib/libsndio/aucat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aucat.c,v 1.54 2012/04/11 06:05:43 ratchov Exp $ */ +/* $OpenBSD: aucat.c,v 1.55 2012/11/02 10:24:58 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -463,6 +463,7 @@ aucat_open(struct aucat *hdl, const char *str, unsigned int mode, hdl->rtodo = sizeof(struct amsg); hdl->wstate = WSTATE_IDLE; hdl->wtodo = 0xdeadbeef; + hdl->maxwrite = 0; /* * say hello to server diff --git a/lib/libsndio/aucat.h b/lib/libsndio/aucat.h index 42dc89f85e7..d7dd4d9cbf2 100644 --- a/lib/libsndio/aucat.h +++ b/lib/libsndio/aucat.h @@ -14,6 +14,7 @@ struct aucat { #define WSTATE_MSG 3 /* message being transferred */ #define WSTATE_DATA 4 /* data being transferred */ unsigned wstate; /* one of above */ + unsigned maxwrite; /* bytes we're allowed to write */ }; int aucat_rmsg(struct aucat *, int *); diff --git a/lib/libsndio/mio_aucat.c b/lib/libsndio/mio_aucat.c index 6f5caa8fbba..28fbd1c8154 100644 --- a/lib/libsndio/mio_aucat.c +++ b/lib/libsndio/mio_aucat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mio_aucat.c,v 1.8 2012/10/27 12:08:25 ratchov Exp $ */ +/* $OpenBSD: mio_aucat.c,v 1.9 2012/11/02 10:24:58 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -54,6 +54,35 @@ static struct mio_ops mio_aucat_ops = { mio_aucat_revents }; +/* + * execute the next message, return 0 if blocked + */ +static int +mio_aucat_runmsg(struct mio_aucat_hdl *hdl) +{ + int delta; + + if (!aucat_rmsg(&hdl->aucat, &hdl->mio.eof)) + return 0; + switch (ntohl(hdl->aucat.rmsg.cmd)) { + case AMSG_DATA: + return 1; + case AMSG_FLOWCTL: + delta = ntohl(hdl->aucat.rmsg.u.ts.delta); + hdl->aucat.maxwrite += delta; + DPRINTF("aucat: flowctl = %d, maxwrite = %d\n", + delta, hdl->aucat.maxwrite); + break; + default: + DPRINTF("mio_aucat_runmsg: unhandled message %u\n", hdl->aucat.rmsg.cmd); + hdl->mio.eof = 1; + return 0; + } + hdl->aucat.rstate = RSTATE_MSG; + hdl->aucat.rtodo = sizeof(struct amsg); + return 1; +} + struct mio_hdl * mio_aucat_open(const char *str, unsigned int mode, int nbio, unsigned int type) @@ -91,7 +120,7 @@ mio_aucat_read(struct mio_hdl *sh, void *buf, size_t len) struct mio_aucat_hdl *hdl = (struct mio_aucat_hdl *)sh; while (hdl->aucat.rstate == RSTATE_MSG) { - if (!aucat_rmsg(&hdl->aucat, &hdl->mio.eof)) + if (!mio_aucat_runmsg(hdl)) return 0; } return aucat_rdata(&hdl->aucat, buf, len, &hdl->mio.eof); @@ -101,8 +130,15 @@ static size_t mio_aucat_write(struct mio_hdl *sh, const void *buf, size_t len) { struct mio_aucat_hdl *hdl = (struct mio_aucat_hdl *)sh; - - return aucat_wdata(&hdl->aucat, buf, len, 1, &hdl->mio.eof); + size_t n; + + if (len <= 0 || hdl->aucat.maxwrite <= 0) + return 0; + if (len > hdl->aucat.maxwrite) + len = hdl->aucat.maxwrite; + n = aucat_wdata(&hdl->aucat, buf, len, 1, &hdl->mio.eof); + hdl->aucat.maxwrite -= n; + return n; } static int @@ -117,6 +153,8 @@ mio_aucat_pollfd(struct mio_hdl *sh, struct pollfd *pfd, int events) struct mio_aucat_hdl *hdl = (struct mio_aucat_hdl *)sh; hdl->events = events; + if (hdl->aucat.maxwrite <= 0) + events &= ~POLLOUT; return aucat_pollfd(&hdl->aucat, pfd, events); } @@ -128,12 +166,16 @@ mio_aucat_revents(struct mio_hdl *sh, struct pollfd *pfd) if (revents & POLLIN) { while (hdl->aucat.rstate == RSTATE_MSG) { - if (!aucat_rmsg(&hdl->aucat, &hdl->mio.eof)) + if (!mio_aucat_runmsg(hdl)) break; } if (hdl->aucat.rstate != RSTATE_DATA) revents &= ~POLLIN; } + if (revents & POLLOUT) { + if (hdl->aucat.maxwrite <= 0) + revents &= ~POLLOUT; + } if (hdl->mio.eof) return POLLHUP; return revents & (hdl->events | POLLHUP); diff --git a/lib/libsndio/sio_aucat.c b/lib/libsndio/sio_aucat.c index bea40dce087..da2a270ac56 100644 --- a/lib/libsndio/sio_aucat.c +++ b/lib/libsndio/sio_aucat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sio_aucat.c,v 1.12 2012/10/27 11:56:04 ratchov Exp $ */ +/* $OpenBSD: sio_aucat.c,v 1.13 2012/11/02 10:24:58 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -35,8 +35,7 @@ struct sio_aucat_hdl { struct sio_hdl sio; struct aucat aucat; - unsigned int rbpf, wbpf; /* read and write bytes-per-frame */ - int maxwrite; /* latency constraint */ + unsigned int rbpf, wbpf; /* read and write bytes-per-frame */ int events; /* events the user requested */ unsigned int curvol, reqvol; /* current and requested volume */ int delta; /* some of received deltas */ @@ -97,23 +96,17 @@ sio_aucat_runmsg(struct sio_aucat_hdl *hdl) return 0; } return 1; - case AMSG_POS: + case AMSG_FLOWCTL: delta = ntohl(hdl->aucat.rmsg.u.ts.delta); - hdl->maxwrite += delta * (int)hdl->wbpf; - DPRINTF("aucat: pos = %d, maxwrite = %d\n", - delta, hdl->maxwrite); - hdl->delta = delta; - if (hdl->delta >= 0) { - sio_onmove_cb(&hdl->sio, hdl->delta); - hdl->delta = 0; - } + hdl->aucat.maxwrite += delta * (int)hdl->wbpf; + DPRINTF("aucat: flowctl = %d, maxwrite = %d\n", + delta, hdl->aucat.maxwrite); break; case AMSG_MOVE: delta = ntohl(hdl->aucat.rmsg.u.ts.delta); - hdl->maxwrite += delta * hdl->wbpf; hdl->delta += delta; DPRINTFN(2, "aucat: move = %d, delta = %d, maxwrite = %d\n", - delta, hdl->delta, hdl->maxwrite); + delta, hdl->delta, hdl->aucat.maxwrite); if (hdl->delta >= 0) { sio_onmove_cb(&hdl->sio, hdl->delta); hdl->delta = 0; @@ -196,10 +189,10 @@ sio_aucat_start(struct sio_hdl *sh) return 0; hdl->wbpf = par.bps * par.pchan; hdl->rbpf = par.bps * par.rchan; - hdl->maxwrite = hdl->wbpf * par.bufsz; + hdl->aucat.maxwrite = hdl->wbpf * par.bufsz; hdl->round = par.round; hdl->delta = 0; - DPRINTF("aucat: start, maxwrite = %d\n", hdl->maxwrite); + DPRINTF("aucat: start, maxwrite = %d\n", hdl->aucat.maxwrite); AMSG_INIT(&hdl->aucat.wmsg); hdl->aucat.wmsg.cmd = htonl(AMSG_START); @@ -233,7 +226,7 @@ sio_aucat_stop(struct sio_hdl *sh) return 0; } if (hdl->aucat.wstate == WSTATE_DATA) { - hdl->maxwrite = hdl->aucat.wtodo; + hdl->aucat.maxwrite = hdl->aucat.wtodo; while (hdl->aucat.wstate != WSTATE_IDLE) { count = hdl->aucat.wtodo; if (count > ZERO_MAX) @@ -427,14 +420,14 @@ sio_aucat_write(struct sio_hdl *sh, const void *buf, size_t len) if (!sio_aucat_buildmsg(hdl)) break; } - if (len <= 0 || hdl->maxwrite <= 0) + if (len <= 0 || hdl->aucat.maxwrite <= 0) return 0; - if (len > hdl->maxwrite) - len = hdl->maxwrite; + if (len > hdl->aucat.maxwrite) + len = hdl->aucat.maxwrite; if (len > hdl->walign) len = hdl->walign; n = aucat_wdata(&hdl->aucat, buf, len, hdl->wbpf, &hdl->sio.eof); - hdl->maxwrite -= n; + hdl->aucat.maxwrite -= n; hdl->walign -= n; if (hdl->walign == 0) hdl->walign = hdl->round * hdl->wbpf; @@ -453,7 +446,7 @@ sio_aucat_pollfd(struct sio_hdl *sh, struct pollfd *pfd, int events) struct sio_aucat_hdl *hdl = (struct sio_aucat_hdl *)sh; hdl->events = events; - if (hdl->maxwrite <= 0) + if (hdl->aucat.maxwrite <= 0) events &= ~POLLOUT; return aucat_pollfd(&hdl->aucat, pfd, events); } @@ -473,7 +466,7 @@ sio_aucat_revents(struct sio_hdl *sh, struct pollfd *pfd) revents &= ~POLLIN; } if (revents & POLLOUT) { - if (hdl->maxwrite <= 0) + if (hdl->aucat.maxwrite <= 0) revents &= ~POLLOUT; } if (hdl->sio.eof) |