Page MenuHomeFreeBSD

D54359.id168580.diff
No OneTemporary

D54359.id168580.diff

Index: sys/dev/sound/midi/midi.c
===================================================================
--- sys/dev/sound/midi/midi.c
+++ sys/dev/sound/midi/midi.c
@@ -89,6 +89,7 @@
static d_read_t midi_read;
static d_write_t midi_write;
static d_poll_t midi_poll;
+static d_kqfilter_t midi_kqfilter;
static struct cdevsw midi_cdevsw = {
.d_version = D_VERSION,
@@ -98,6 +99,7 @@
.d_write = midi_write,
.d_ioctl = midi_ioctl,
.d_poll = midi_poll,
+ .d_kqfilter = midi_kqfilter,
.d_name = "rmidi",
};
@@ -218,6 +220,9 @@
m->channel = channel;
m->cookie = cookie;
+ knlist_init_mtx(&m->rsel.si_note, &m->qlock);
+ knlist_init_mtx(&m->wsel.si_note, &m->qlock);
+
if (MPU_INIT(m, cookie))
goto err2;
@@ -337,6 +342,7 @@
wakeup(&m->rchan);
m->rchan = 0;
}
+ KNOTE_LOCKED(&m->rsel.si_note, 0);
selwakeup(&m->rsel);
mtx_unlock(&m->qlock);
return used;
@@ -371,6 +377,7 @@
wakeup(&m->wchan);
m->wchan = 0;
}
+ KNOTE_LOCKED(&m->wsel.si_note, 0);
selwakeup(&m->wsel);
}
mtx_unlock(&m->qlock);
@@ -687,6 +694,10 @@
mtx_assert(&m->lock, MA_OWNED);
MIDI_DEBUG(3, printf("midi_destroy\n"));
+ knlist_clear(&m->rsel.si_note, 1);
+ knlist_destroy(&m->rsel.si_note);
+ knlist_clear(&m->wsel.si_note, 1);
+ knlist_destroy(&m->wsel.si_note);
m->dev->si_drv1 = NULL;
mtx_unlock(&m->lock); /* XXX */
destroy_dev(m->dev);
@@ -741,6 +752,65 @@
return retval;
}
+static void
+midi_kqdetach(struct knote *kn)
+{
+ struct snd_midi *m = kn->kn_hook;
+ if (kn->kn_filter == EVFILT_READ)
+ knlist_remove(&m->rsel.si_note, kn, 0);
+ else if (kn->kn_filter == EVFILT_WRITE)
+ knlist_remove(&m->wsel.si_note, kn, 0);
+}
+
+static int
+midi_kqfilter_event(struct knote *kn, long hint)
+{
+ struct snd_midi *m = kn->kn_hook;
+ if (/* there's something wrong */ false) {
+ kn->kn_data = EBADF;
+ kn->kn_flags |= EV_ERROR;
+ return (1);
+ }
+ switch (kn->kn_filter) {
+ case EVFILT_READ:
+ kn->kn_data = MIDIQ_AVAIL(m->inq);
+ break;
+ case EVFILT_WRITE:
+ kn->kn_data = MIDIQ_AVAIL(m->outq);
+ break;
+ }
+ return (1);
+}
+
+static const struct filterops midi_kqfilter_ops = {
+ .f_isfd = 1,
+ .f_detach = midi_kqdetach,
+ .f_event = midi_kqfilter_event,
+};
+
+static int
+midi_kqfilter(struct cdev *dev, struct knote *kn)
+{
+ int error = 0;
+ struct snd_midi *m = dev->si_drv1;
+
+ kn->kn_hook = m;
+ kn->kn_fop = &midi_kqfilter_ops;
+
+ switch (kn->kn_filter) {
+ case EVFILT_READ:
+ knlist_add(&m->rsel.si_note, kn, 1);
+ break;
+ case EVFILT_WRITE:
+ knlist_add(&m->wsel.si_note, kn, 1);
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ return (error);
+}
+
static int
midi_modevent(module_t mod, int type, void *data)
{

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 15, 6:46 PM (10 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27653882
Default Alt Text
D54359.id168580.diff (2 KB)

Event Timeline