mirror of https://github.com/ericonr/sndio.git
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.
This commit is contained in:
parent
ccdecf59c4
commit
49190bbba1
|
@ -443,7 +443,8 @@ port_exit(void *arg)
|
||||||
|
|
||||||
if (log_level >= 3) {
|
if (log_level >= 3) {
|
||||||
port_log(p);
|
port_log(p);
|
||||||
log_puts(": exit\n");
|
log_puts(": port exit\n");
|
||||||
|
panic();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -489,6 +490,37 @@ port_del(struct port *c)
|
||||||
xfree(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 *
|
struct port *
|
||||||
port_bynum(int num)
|
port_bynum(int num)
|
||||||
{
|
{
|
||||||
|
@ -518,14 +550,24 @@ port_open(struct port *c)
|
||||||
int
|
int
|
||||||
port_close(struct port *c)
|
port_close(struct port *c)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
struct midi *ep;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (c->state == PORT_CFG) {
|
if (c->state == PORT_CFG) {
|
||||||
port_log(c);
|
port_log(c);
|
||||||
log_puts(": can't close port (not opened)\n");
|
log_puts(": can't close port (not opened)\n");
|
||||||
|
panic();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
port_mio_close(c);
|
|
||||||
c->state = PORT_CFG;
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,6 @@ struct port {
|
||||||
unsigned int state;
|
unsigned int state;
|
||||||
char *path;
|
char *path;
|
||||||
struct midi *midi;
|
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_new(char *, unsigned int);
|
||||||
struct port *port_bynum(int);
|
struct port *port_bynum(int);
|
||||||
void port_del(struct port *);
|
void port_del(struct port *);
|
||||||
|
int port_ref(struct port *);
|
||||||
|
void port_unref(struct port *);
|
||||||
int port_init(struct port *);
|
int port_init(struct port *);
|
||||||
void port_done(struct port *);
|
void port_done(struct port *);
|
||||||
int port_close(struct port *);
|
int port_close(struct port *);
|
||||||
|
|
|
@ -151,6 +151,10 @@ sock_close(struct sock *f)
|
||||||
midi_del(f->midi);
|
midi_del(f->midi);
|
||||||
f->midi = NULL;
|
f->midi = NULL;
|
||||||
}
|
}
|
||||||
|
if (f->port) {
|
||||||
|
port_unref(f->port);
|
||||||
|
f->port = NULL;
|
||||||
|
}
|
||||||
file_del(f->file);
|
file_del(f->file);
|
||||||
close(f->fd);
|
close(f->fd);
|
||||||
xfree(f);
|
xfree(f);
|
||||||
|
@ -850,6 +854,7 @@ sock_hello(struct sock *f)
|
||||||
}
|
}
|
||||||
f->pstate = SOCK_INIT;
|
f->pstate = SOCK_INIT;
|
||||||
if (mode & MODE_MIDIMASK) {
|
if (mode & MODE_MIDIMASK) {
|
||||||
|
f->port = NULL;
|
||||||
f->slot = NULL;
|
f->slot = NULL;
|
||||||
f->midi = midi_new(&sock_midiops, f, mode);
|
f->midi = midi_new(&sock_midiops, f, mode);
|
||||||
if (f->midi == NULL)
|
if (f->midi == NULL)
|
||||||
|
@ -864,8 +869,9 @@ sock_hello(struct sock *f)
|
||||||
midi_tag(f->midi, p->devnum);
|
midi_tag(f->midi, p->devnum);
|
||||||
} else if (p->devnum < 48) {
|
} else if (p->devnum < 48) {
|
||||||
c = port_bynum(p->devnum - 32);
|
c = port_bynum(p->devnum - 32);
|
||||||
if (c == NULL)
|
if (c == NULL || !port_ref(c))
|
||||||
return 0;
|
return 0;
|
||||||
|
f->port = c;
|
||||||
midi_link(f->midi, c->midi);
|
midi_link(f->midi, c->midi);
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -58,7 +58,8 @@ struct sock {
|
||||||
int lastvol; /* last volume */
|
int lastvol; /* last volume */
|
||||||
struct opt *opt; /* "subdevice" definition */
|
struct opt *opt; /* "subdevice" definition */
|
||||||
struct slot *slot; /* audio device slot number */
|
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 */
|
char who[12]; /* label, mostly for debugging */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue