diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2012-11-30 20:48:01 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2012-11-30 20:48:01 +0000 |
commit | c06063a893a41e0a01a2ddd5e34be323daa2b44a (patch) | |
tree | ada751bd285efa24826f4f9af46fa746606007d6 | |
parent | 34829fa6736a743192f05481ecf0fefb8b9fb47f (diff) |
For MIDI ports, use the same open/close logic as for audio devices:
drop clients using it when the port is closed (eg. umidi disconnected)
and try to reopen it whenever a new client connects.
-rw-r--r-- | usr.bin/sndiod/midi.c | 48 | ||||
-rw-r--r-- | usr.bin/sndiod/midi.h | 5 | ||||
-rw-r--r-- | usr.bin/sndiod/sock.c | 10 | ||||
-rw-r--r-- | usr.bin/sndiod/sock.h | 5 |
4 files changed, 59 insertions, 9 deletions
diff --git a/usr.bin/sndiod/midi.c b/usr.bin/sndiod/midi.c index f599d21f94c..02e2c659904 100644 --- a/usr.bin/sndiod/midi.c +++ b/usr.bin/sndiod/midi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: midi.c,v 1.2 2012/11/30 20:30:24 ratchov Exp $ */ +/* $OpenBSD: midi.c,v 1.3 2012/11/30 20:48:00 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -442,7 +442,8 @@ port_exit(void *arg) if (log_level >= 3) { port_log(p); - log_puts(": exit\n"); + log_puts(": port exit\n"); + panic(); } #endif } @@ -488,6 +489,37 @@ port_del(struct port *c) xfree(c); } +int +port_ref(struct port *c) +{ +#ifdef DEBUG + if (log_level >= 3) { + port_log(c); + log_puts(": port requested\n"); + } +#endif + if (c->state == PORT_CFG && !port_open(c)) + return 0; + return 1; +} + +void +port_unref(struct port *c) +{ + int i, rxmask; + +#ifdef DEBUG + if (log_level >= 3) { + port_log(c); + log_puts(": port released\n"); + } +#endif + for (rxmask = 0, i = 0; i < MIDI_NEP; i++) + rxmask |= midi_ep[i].txmask; + if ((rxmask & c->midi->self) == 0 && c->state == PORT_INIT) + port_close(c); +} + struct port * port_bynum(int num) { @@ -517,14 +549,24 @@ port_open(struct port *c) int port_close(struct port *c) { + int i; + struct midi *ep; #ifdef DEBUG if (c->state == PORT_CFG) { port_log(c); log_puts(": can't close port (not opened)\n"); + panic(); } #endif - port_mio_close(c); c->state = PORT_CFG; + port_mio_close(c); + + for (i = 0; i < MIDI_NEP; i++) { + ep = midi_ep + i; + if ((ep->txmask & c->midi->self) || + (c->midi->txmask & ep->self)) + ep->ops->exit(ep->arg); + } return 1; } diff --git a/usr.bin/sndiod/midi.h b/usr.bin/sndiod/midi.h index 34ebfa370e5..b3a76076153 100644 --- a/usr.bin/sndiod/midi.h +++ b/usr.bin/sndiod/midi.h @@ -1,4 +1,4 @@ -/* $OpenBSD: midi.h,v 1.2 2012/11/30 20:30:24 ratchov Exp $ */ +/* $OpenBSD: midi.h,v 1.3 2012/11/30 20:48:00 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -89,7 +89,6 @@ struct port { unsigned int state; char *path; struct midi *midi; - unsigned int refs; }; /* @@ -113,6 +112,8 @@ void midi_link(struct midi *, struct midi *); struct port *port_new(char *, unsigned int); struct port *port_bynum(int); void port_del(struct port *); +int port_ref(struct port *); +void port_unref(struct port *); int port_init(struct port *); void port_done(struct port *); int port_close(struct port *); diff --git a/usr.bin/sndiod/sock.c b/usr.bin/sndiod/sock.c index e7e9b6678ae..456a297ad94 100644 --- a/usr.bin/sndiod/sock.c +++ b/usr.bin/sndiod/sock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sock.c,v 1.2 2012/11/30 20:30:24 ratchov Exp $ */ +/* $OpenBSD: sock.c,v 1.3 2012/11/30 20:48:00 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -151,6 +151,10 @@ sock_close(struct sock *f) midi_del(f->midi); f->midi = NULL; } + if (f->port) { + port_unref(f->port); + f->port = NULL; + } file_del(f->file); close(f->fd); xfree(f); @@ -850,6 +854,7 @@ sock_hello(struct sock *f) } f->pstate = SOCK_INIT; if (mode & MODE_MIDIMASK) { + f->port = NULL; f->slot = NULL; f->midi = midi_new(&sock_midiops, f, mode); if (f->midi == NULL) @@ -864,8 +869,9 @@ sock_hello(struct sock *f) midi_tag(f->midi, p->devnum); } else if (p->devnum < 48) { c = port_bynum(p->devnum - 32); - if (c == NULL) + if (c == NULL || !port_ref(c)) return 0; + f->port = c; midi_link(f->midi, c->midi); } else return 0; diff --git a/usr.bin/sndiod/sock.h b/usr.bin/sndiod/sock.h index 94d23f21598..ccf00345c54 100644 --- a/usr.bin/sndiod/sock.h +++ b/usr.bin/sndiod/sock.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sock.h,v 1.1 2012/11/23 07:03:28 ratchov Exp $ */ +/* $OpenBSD: sock.h,v 1.2 2012/11/30 20:48:00 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -58,7 +58,8 @@ struct sock { int lastvol; /* last volume */ struct opt *opt; /* "subdevice" definition */ struct slot *slot; /* audio device slot number */ - struct midi *midi; /* midi endpoint number */ + struct midi *midi; /* midi endpoint */ + struct port *port; /* midi port */ char who[12]; /* label, mostly for debugging */ }; |