From 5142109f22d71571e6d6e3f4c61d57cc1cf57c3a Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Sat, 3 Nov 2012 17:30:30 +0100 Subject: [PATCH] make file i/o able to cross fifo bundary --- sndiod/abuf.c | 4 +- sndiod/abuf.h | 2 +- sndiod/defs.h | 2 +- sndiod/dev.c | 24 ++++++----- sndiod/file.c | 2 +- sndiod/listen.c | 6 +-- sndiod/midi.c | 18 ++++---- sndiod/miofile.c | 3 +- sndiod/opt.c | 2 +- sndiod/sock.c | 104 +++++++++++++++++++---------------------------- sndiod/utils.h | 6 +-- 11 files changed, 79 insertions(+), 94 deletions(-) diff --git a/sndiod/abuf.c b/sndiod/abuf.c index bd8cc54..ecfc7dd 100644 --- a/sndiod/abuf.c +++ b/sndiod/abuf.c @@ -43,9 +43,9 @@ abuf_log(struct abuf *buf) #endif void -abuf_init(struct abuf *buf, unsigned int len) +abuf_init(struct abuf *buf, unsigned int len, char *tag) { - buf->data = xmalloc(len); + buf->data = xmalloc(len, tag); buf->len = len; buf->used = 0; buf->start = 0; diff --git a/sndiod/abuf.h b/sndiod/abuf.h index 84b67ee..827fa30 100644 --- a/sndiod/abuf.h +++ b/sndiod/abuf.h @@ -24,7 +24,7 @@ struct abuf { unsigned char *data; }; -void abuf_init(struct abuf *, unsigned int); +void abuf_init(struct abuf *, unsigned int, char *); void abuf_done(struct abuf *); void abuf_log(struct abuf *); unsigned char *abuf_rgetblk(struct abuf *, int *); diff --git a/sndiod/defs.h b/sndiod/defs.h index c90b1fe..b63335d 100644 --- a/sndiod/defs.h +++ b/sndiod/defs.h @@ -31,7 +31,7 @@ extern unsigned int log_level; /* * MIDI buffer size */ -#define MIDI_BUFSZ 125 /* 1/25 second at 31.25kbit/s */ +#define MIDI_BUFSZ 125 /* 1 second at 31.25kbit/s */ /* * units used for MTC clock. diff --git a/sndiod/dev.c b/sndiod/dev.c index 76cb046..dcd7d3b 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -974,7 +974,7 @@ dev_new(char *path, struct aparams *par, log_puts("too many devices\n"); return NULL; } - d = xmalloc(sizeof(struct dev)); + d = xmalloc(sizeof(struct dev), "dev"); d->num = dev_sndnum++; d->midi = midi_new(&dev_midiops, d, MODE_MIDIIN | MODE_MIDIOUT); midi_tag(d->midi, d->num); @@ -1057,14 +1057,16 @@ dev_open(struct dev *d) /* * Create device <-> demuxer buffer */ - d->rbuf = xmalloc(d->round * d->rchan * sizeof(adata_t)); + d->rbuf = xmalloc(d->round * d->rchan * sizeof(adata_t), + "dev_rbuf"); /* * Insert a converter, if needed. */ if (!aparams_native(&d->par)) { dec_init(&d->dec, &d->par, d->rchan); - d->decbuf = xmalloc(d->round * d->rchan * d->par.bps); + d->decbuf = xmalloc(d->round * d->rchan * d->par.bps, + "dev_dec"); } else d->decbuf = NULL; } @@ -1072,7 +1074,7 @@ dev_open(struct dev *d) /* * Create device <-> mixer buffer */ - d->pbuf = xmalloc(d->bufsz * d->pchan * sizeof(adata_t)); + d->pbuf = xmalloc(d->bufsz * d->pchan * sizeof(adata_t), "dev_pbuf"); d->poffs = 0; d->mode |= MODE_MON; @@ -1081,7 +1083,7 @@ dev_open(struct dev *d) */ if (!aparams_native(&d->par)) { enc_init(&d->enc, &d->par, d->pchan); - d->encbuf = xmalloc(d->round * d->pchan * d->par.bps); + d->encbuf = xmalloc(d->round * d->pchan * d->par.bps, "dev_enc"); } else d->encbuf = NULL; } @@ -1683,13 +1685,13 @@ slot_attach(struct slot *s) if (!aparams_native(&s->par)) { dec_init(&s->mix.dec, &s->par, slot_nch); s->mix.decbuf = - xmalloc(d->round * slot_nch * sizeof(adata_t)); + xmalloc(d->round * slot_nch * sizeof(adata_t), "slot_mix_dec"); } if (s->rate != d->rate) { resamp_init(&s->mix.resamp, s->round, d->round, slot_nch); s->mix.resampbuf = - xmalloc(d->round * slot_nch * sizeof(adata_t)); + xmalloc(d->round * slot_nch * sizeof(adata_t), "slot_mix_resamp"); } #ifdef DEBUG if (log_level >= 3) { @@ -1738,12 +1740,12 @@ slot_attach(struct slot *s) resamp_init(&s->sub.resamp, d->round, s->round, slot_nch); s->sub.resampbuf = - xmalloc(d->round * slot_nch * sizeof(adata_t)); + xmalloc(d->round * slot_nch * sizeof(adata_t), "slot_sub_resamp"); } if (!aparams_native(&s->par)) { enc_init(&s->sub.enc, &s->par, slot_nch); s->sub.encbuf = - xmalloc(d->round * slot_nch * sizeof(adata_t)); + xmalloc(d->round * slot_nch * sizeof(adata_t), "slot_sub_enc"); } #ifdef DEBUG @@ -1818,7 +1820,7 @@ slot_start(struct slot *s) #endif s->mix.bpf = s->par.bps * (s->mix.slot_cmax - s->mix.slot_cmin + 1); - abuf_init(&s->mix.buf, bufsz * s->mix.bpf); + abuf_init(&s->mix.buf, bufsz * s->mix.bpf, "slot_mix"); } if (s->mode & MODE_RECMASK) { #ifdef DEBUG @@ -1833,7 +1835,7 @@ slot_start(struct slot *s) #endif s->sub.bpf = s->par.bps * (s->sub.slot_cmax - s->sub.slot_cmin + 1); - abuf_init(&s->sub.buf, bufsz * s->sub.bpf); + abuf_init(&s->sub.buf, bufsz * s->sub.bpf, "slot_sub"); } s->mix.weight = MIDI_TO_ADATA(MIDI_MAXCTL); #ifdef DEBUG diff --git a/sndiod/file.c b/sndiod/file.c index 8210f7a..00c6d6b 100644 --- a/sndiod/file.c +++ b/sndiod/file.c @@ -230,7 +230,7 @@ file_new(struct fileops *ops, void *arg, char *name, unsigned int nfds) #endif return NULL; } - f = xmalloc(sizeof(struct file)); + f = xmalloc(sizeof(struct file), "file"); f->nfds = nfds; f->ops = ops; f->arg = arg; diff --git a/sndiod/listen.c b/sndiod/listen.c index 11df33e..4eba5e8 100644 --- a/sndiod/listen.c +++ b/sndiod/listen.c @@ -109,11 +109,11 @@ listen_new_un(char *path) goto bad_close; } umask(oldumask); - f = xmalloc(sizeof(struct listen)); + f = xmalloc(sizeof(struct listen), "listen_un"); f->file = file_new(&listen_fileops, f, path, 1); if (f->file == NULL) goto bad_close; - f->path = xstrdup(path); + f->path = xstrdup(path, "listen_path"); if (f->path == NULL) { perror("strdup"); exit(1); @@ -174,7 +174,7 @@ listen_new_tcp(char *addr, unsigned int port) perror("listen"); goto bad_close; } - f = xmalloc(sizeof(struct listen)); + f = xmalloc(sizeof(struct listen), "listen_tcp"); f->file = file_new(&listen_fileops, f, addr, 1); if (f == NULL) { bad_close: diff --git a/sndiod/midi.c b/sndiod/midi.c index 922ded0..e4f3d75 100644 --- a/sndiod/midi.c +++ b/sndiod/midi.c @@ -84,8 +84,10 @@ midi_ontimo(void *arg) for (i = MIDI_NEP, ep = midi_ep; i > 0; i--, ep++) { ep->tickets = MIDI_XFER; - if (ep->ibuf.used > 0) - midi_in(ep); + if (ep->ibuf.used > 0) { + while (midi_in(ep)) + ; /* nothing */ + } } timo_add(&midi_timo, MIDI_TIMO); } @@ -130,10 +132,10 @@ midi_new(struct midiops *ops, void *arg, int mode) * to client input */ if (ep->mode & MODE_MIDIOUT) { - abuf_init(&ep->ibuf, MIDI_BUFSZ); + abuf_init(&ep->ibuf, MIDI_BUFSZ, "midi_ibuf"); } if (ep->mode & MODE_MIDIIN) { - abuf_init(&ep->obuf, MIDI_BUFSZ); + abuf_init(&ep->obuf, MIDI_BUFSZ, "midi_obuf"); } return ep; } @@ -252,9 +254,9 @@ midi_in(struct midi *ep) return 0; } idata = abuf_rgetblk(&ep->ibuf, &icount); - if (icount > ep->tickets) - icount = ep->tickets; - ep->tickets -= icount; + //if (icount > ep->tickets) + // icount = ep->tickets; + //ep->tickets -= icount; #ifdef DEBUG if (log_level >= 4) { midi_log(ep); @@ -404,7 +406,7 @@ port_new(char *path, unsigned int mode) { struct port *c; - c = xmalloc(sizeof(struct port)); + c = xmalloc(sizeof(struct port), "port"); c->path = path; c->state = PORT_CFG; c->midi = midi_new(&port_midiops, c, mode); diff --git a/sndiod/miofile.c b/sndiod/miofile.c index 220102a..26adf52 100644 --- a/sndiod/miofile.c +++ b/sndiod/miofile.c @@ -99,7 +99,8 @@ port_mio_in(void *arg) if (n == 0) break; abuf_wcommit(&ep->ibuf, n); - midi_in(ep); + while (midi_in(ep)) + ; /* nothing */ if (n < count) break; } diff --git a/sndiod/opt.c b/sndiod/opt.c index ea5bf5f..d5aed03 100644 --- a/sndiod/opt.c +++ b/sndiod/opt.c @@ -46,7 +46,7 @@ opt_new(char *name, struct dev *dev, exit(1); } } - o = xmalloc(sizeof(struct opt)); + o = xmalloc(sizeof(struct opt), "opt"); if (mode & MODE_PLAY) { o->pmin = pmin; o->pmax = pmax; diff --git a/sndiod/sock.c b/sndiod/sock.c index ee64d67..a038b9d 100644 --- a/sndiod/sock.c +++ b/sndiod/sock.c @@ -281,7 +281,7 @@ sock_new(int fd) { struct sock *f; - f = xmalloc(sizeof(struct sock)); + f = xmalloc(sizeof(struct sock), "sock"); f->pstate = SOCK_AUTH; f->opt = NULL; f->slot = NULL; @@ -521,32 +521,16 @@ sock_rdata(struct sock *f) buf = &f->slot->mix.buf; else buf = &f->midi->ibuf; - data = abuf_wgetblk(buf, &count) + f->rsize - f->rtodo; -#ifdef DEBUG - /* - * XXX: this can happen in MIDIOUT mode, since we dont - * have flow control - */ - if (count < f->rtodo) { - sock_log(f); - log_puts(": data read buffer overrun\n"); - panic(); - } -#endif - n = sock_fdread(f, data, f->rtodo); - if (n == 0) - return 0; - if (n < f->rtodo) { + while (f->rtodo > 0) { + data = abuf_wgetblk(buf, &count); + if (count > f->rtodo) + count = f->rtodo; + n = sock_fdread(f, data, count); + if (n == 0) + return 0; f->rtodo -= n; - return 0; + abuf_wcommit(buf, n); } - - /* - * XXX: commit data earlier, don't sacrify a full block in case - * of xrun - */ - abuf_wcommit(buf, f->rsize); - f->rtodo = 0; #ifdef DEBUG if (log_level >= 4) { sock_log(f); @@ -556,18 +540,9 @@ sock_rdata(struct sock *f) if (f->slot) slot_write(f->slot); if (f->midi) { - midi_in(f->midi); -#ifdef DEBUG - if (f->midi->ibuf.used > 0) { - if (log_level >= 1) { - sock_log(f); - log_puts(": midi buffer not emptied\n"); - } - panic(); - } -#endif - f->midi->ibuf.start = 0; - f->fillpending += f->rsize; + while (midi_in(f->midi)) + ; /* nothing */ + f->fillpending += f->midi->ibuf.len - f->midi->ibuf.used; } return 1; } @@ -591,31 +566,37 @@ sock_wdata(struct sock *f) panic(); } #endif - if (f->slot) { - buf = &f->slot->sub.buf; - if (f->pstate == SOCK_STOP) - data = dummy; - else { - data = abuf_rgetblk(buf, &count) + f->wsize - f->wtodo; + if (f->pstate == SOCK_STOP) { + while (f->wtodo > 0) { + n = sock_fdwrite(f, dummy, f->wtodo); + if (n == 0) + return 0; + f->wtodo -= n; } +#ifdef DEBUG + if (log_level >= 4) { + sock_log(f); + log_puts(": zero-filled remaining block\n"); + } +#endif + return 1; } - if (f->midi) { + if (f->slot) + buf = &f->slot->sub.buf; + else buf = &f->midi->obuf; - data = abuf_rgetblk(buf, &count) + f->wsize - f->wtodo; - } - n = sock_fdwrite(f, data, f->wtodo); - if (n == 0) - return 0; - if (n < f->wtodo) { + while (f->wtodo > 0) { + data = abuf_rgetblk(buf, &count); + if (count > f->wtodo) + count = f->wtodo; + n = sock_fdwrite(f, data, f->wtodo); + if (n == 0) + return 0; f->wtodo -= n; - return 0; + abuf_rdiscard(buf, n); } - if (f->pstate != SOCK_STOP) { - abuf_rdiscard(buf, f->wsize); - if (f->slot) - slot_read(f->slot); - } - f->wtodo = 0; + if (f->slot) + slot_read(f->slot); #ifdef DEBUG if (log_level >= 4) { sock_log(f); @@ -877,6 +858,7 @@ sock_hello(struct sock *f) #endif return 0; } + f->pstate = SOCK_INIT; if (mode & MODE_MIDIMASK) { f->slot = NULL; f->midi = midi_new(&sock_midiops, f, mode); @@ -945,7 +927,6 @@ sock_hello(struct sock *f) s->mix.maxweight = f->opt->maxweight; s->dup = f->opt->dup; /* XXX: must convert to slot rate */ - f->pstate = SOCK_INIT; f->slot = s; return 1; } @@ -1401,9 +1382,8 @@ sock_buildmsg(struct sock *f) } if (f->midi != NULL && f->midi->obuf.used > 0) { - size = f->midi->obuf.len - f->midi->obuf.start; - if (size > f->midi->obuf.used) - size = f->midi->obuf.used; + /* XXX: use tickets */ + size = f->midi->obuf.used; if (size > AMSG_DATAMAX) size = AMSG_DATAMAX; AMSG_INIT(&f->wmsg); @@ -1418,7 +1398,6 @@ sock_buildmsg(struct sock *f) * If data available, build a DATA message. */ if (f->slot != NULL && f->slot->sub.buf.used > 0 && f->wmax > 0) { - /* XXX: round to bpf */ size = f->slot->sub.buf.used; if (size > AMSG_DATAMAX) size = AMSG_DATAMAX; @@ -1426,6 +1405,7 @@ sock_buildmsg(struct sock *f) size = f->walign; if (size > f->wmax) size = f->wmax; + size -= size % f->slot->sub.bpf; #ifdef DEBUG if (size == 0) { sock_log(f); diff --git a/sndiod/utils.h b/sndiod/utils.h index d7de231..23b4490 100644 --- a/sndiod/utils.h +++ b/sndiod/utils.h @@ -32,9 +32,9 @@ char *mem_strdup(const char *, char *); void mem_free(void *); void mem_stats(void); -#define xmalloc(s) (mem_alloc((s), (char *)__func__)) -#define xstrdup(s) (mem_strdup((s), (char *)__func__)) -#define xfree(p) (mem_free((p))) +#define xmalloc(size, tag) (mem_alloc((size), (tag))) +#define xstrdup(str, tag) (mem_strdup((str), (tag))) +#define xfree(ptr) (mem_free(ptr)) void memrnd(void *, size_t);