summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2012-11-30 20:48:01 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2012-11-30 20:48:01 +0000
commitc06063a893a41e0a01a2ddd5e34be323daa2b44a (patch)
treeada751bd285efa24826f4f9af46fa746606007d6
parent34829fa6736a743192f05481ecf0fefb8b9fb47f (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.c48
-rw-r--r--usr.bin/sndiod/midi.h5
-rw-r--r--usr.bin/sndiod/sock.c10
-rw-r--r--usr.bin/sndiod/sock.h5
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 */
};