diff --git a/sndiod/midi.c b/sndiod/midi.c index 7c91ec9..643d888 100644 --- a/sndiod/midi.c +++ b/sndiod/midi.c @@ -190,6 +190,25 @@ midi_tag(struct midi *ep, unsigned int tag) t->txmask |= ep->self; } +/* + * return the list of tags + */ +unsigned int +midi_tags(struct midi *ep) +{ + int i; + struct midithru *t; + unsigned int tags; + + tags = 0; + for (i = 0; i < MIDITHRU_NMAX; i++) { + t = midithru + i; + if ((t->txmask | t->rxmask) & ep->self) + tags |= 1 << i; + } + return tags; +} + /* * broadcast the given message to other endpoints */ diff --git a/sndiod/midi.h b/sndiod/midi.h index e2ce168..cff3576 100644 --- a/sndiod/midi.h +++ b/sndiod/midi.h @@ -110,6 +110,7 @@ void midi_out(struct midi *, unsigned char *, int); void midi_send(struct midi *, unsigned char *, int); void midi_fill(struct midi *); void midi_tag(struct midi *, unsigned int); +unsigned int midi_tags(struct midi *); void midi_link(struct midi *, struct midi *); void port_log(struct port *); diff --git a/sndiod/sock.c b/sndiod/sock.c index 6eb2400..28c75b5 100644 --- a/sndiod/sock.c +++ b/sndiod/sock.c @@ -130,7 +130,9 @@ sock_log(struct sock *f) void sock_close(struct sock *f) { + struct dev *d; struct sock **pf; + unsigned int tags, i; for (pf = &sock_list; *pf != f; pf = &(*pf)->next) { #ifdef DEBUG @@ -155,6 +157,11 @@ sock_close(struct sock *f) f->slot = NULL; } if (f->midi) { + tags = midi_tags(f->midi); + for (i = 0; i < DEV_NMAX; i++) { + if ((tags & (1 << i)) && (d = dev_bynum(i)) != NULL) + dev_unref(d); + } midi_del(f->midi); f->midi = NULL; } @@ -861,6 +868,8 @@ sock_hello(struct sock *f) d = dev_bynum(p->devnum); if (d == NULL) return 0; + if (!dev_ref(d)) + return 0; midi_tag(f->midi, p->devnum); } else if (p->devnum < 32) { midi_tag(f->midi, p->devnum);