Page MenuHomeFreeBSD

D53029.id163950.diff
No OneTemporary

D53029.id163950.diff

diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -313,8 +313,10 @@
bs = c->bufsoft;
if (CHN_EMPTY(c, children.busy)) {
- if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c))
+ if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c)) {
selwakeuppri(sndbuf_getsel(bs), PRIBIO);
+ KNOTE_LOCKED(&bs->sel.si_note, 0);
+ }
CHN_BROADCAST(&c->intr_cv);
} else {
CHN_FOREACH(ch, c, children.busy) {
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -42,6 +42,7 @@
#include <sys/lock.h>
#include <sys/rwlock.h>
#include <sys/sysent.h>
+#include <sys/conf.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
@@ -81,6 +82,7 @@
static d_poll_t dsp_poll;
static d_mmap_t dsp_mmap;
static d_mmap_single_t dsp_mmap_single;
+static d_kqfilter_t dsp_kqueue;
struct cdevsw dsp_cdevsw = {
.d_version = D_VERSION,
@@ -89,6 +91,7 @@
.d_write = dsp_write,
.d_ioctl = dsp_ioctl,
.d_poll = dsp_poll,
+ .d_kqfilter = dsp_kqueue,
.d_mmap = dsp_mmap,
.d_mmap_single = dsp_mmap_single,
.d_name = "dsp",
@@ -235,6 +238,7 @@
chn_vpc_reset(*ch, SND_VOL_C_PCM, 0);
CHN_UNLOCK(*ch);
+ knlist_init_mtx(&(*ch)->bufsoft->sel.si_note, (*ch)->lock);
return (0);
}
@@ -264,10 +268,16 @@
rdch = priv->rdch;
wrch = priv->wrch;
- if (rdch != NULL)
+ if (rdch != NULL) {
+ knlist_clear(&rdch->bufsoft->sel.si_note, 0);
+ knlist_destroy(&rdch->bufsoft->sel.si_note);
CHN_REMOVE(d, rdch, channels.pcm.opened);
- if (wrch != NULL)
+ }
+ if (wrch != NULL) {
+ knlist_clear(&wrch->bufsoft->sel.si_note, 0);
+ knlist_destroy(&wrch->bufsoft->sel.si_note);
CHN_REMOVE(d, wrch, channels.pcm.opened);
+ }
if (rdch != NULL || wrch != NULL) {
PCM_UNLOCK(d);
@@ -2962,6 +2972,105 @@
return (ret);
}
+static void
+dsp_kqdetach(struct knote *kn)
+{
+ struct pcm_channel *ch = kn->kn_hook;
+ struct snd_dbuf *bs;
+
+ bs = ch->bufsoft;
+ knlist_remove(&bs->sel.si_note, kn, 0);
+}
+
+static int
+dsp_read_filter(struct knote *kn, long hint)
+{
+ struct dsp_cdevpriv *priv;
+ struct snddev_info *d;
+ struct pcm_channel *ch = kn->kn_hook;
+ int err;
+
+ if ((err = devfs_get_cdevpriv((void **)&priv)) != 0)
+ return (err);
+ d = priv->sc;
+ PCM_GIANT_ENTER(d);
+ dsp_lock_chans(priv, FREAD);
+
+ if (ch != NULL && !(ch->flags & CHN_F_DEAD) && kn->kn_filter == EVFILT_READ)
+ kn->kn_data = sndbuf_getallocsize(ch->bufsoft);
+ else
+ kn->kn_data = 0;
+
+ dsp_unlock_chans(priv, FREAD);
+ PCM_GIANT_LEAVE(d);
+ return (kn->kn_data > 0 ? 1 : 0);
+}
+
+static int
+dsp_write_filter(struct knote *kn, long hint)
+{
+ struct dsp_cdevpriv *priv;
+ struct snddev_info *d;
+ struct pcm_channel *ch = kn->kn_hook;
+ int err;
+
+ if ((err = devfs_get_cdevpriv((void **)&priv)) != 0)
+ return (err);
+ d = priv->sc;
+ PCM_GIANT_ENTER(d);
+ dsp_lock_chans(priv, FWRITE);
+
+ if (ch != NULL && !(ch->flags & CHN_F_DEAD) && kn->kn_filter == EVFILT_WRITE)
+ kn->kn_data = sndbuf_getallocsize(ch->bufsoft);
+ else
+ kn->kn_data = 0;
+
+ dsp_unlock_chans(priv, FWRITE);
+ PCM_GIANT_LEAVE(d);
+ return (kn->kn_data > 0 ? 1 : 0);
+}
+
+static const struct filterops dsp_read_filtops = {
+ .f_isfd = 1,
+ .f_detach = dsp_kqdetach,
+ .f_event = dsp_read_filter,
+};
+
+static const struct filterops dsp_write_filtops = {
+ .f_isfd = 1,
+ .f_detach = dsp_kqdetach,
+ .f_event = dsp_write_filter,
+};
+
+static int
+dsp_kqueue(struct cdev *dev, struct knote *kn)
+{
+ int err;
+ struct dsp_cdevpriv *priv;
+
+ if ((err = devfs_get_cdevpriv((void **)&priv)) != 0)
+ return (err);
+ switch (kn->kn_filter) {
+ case EVFILT_READ:
+ kn->kn_hook = priv->rdch;
+ kn->kn_fop = &dsp_read_filtops;
+ knlist_add(&priv->rdch->bufsoft->sel.si_note, kn, 0);
+ err = 0;
+ break;
+ case EVFILT_WRITE:
+ kn->kn_hook = priv->wrch;
+ kn->kn_fop = &dsp_write_filtops;
+ knlist_add(&priv->wrch->bufsoft->sel.si_note, kn, 0);
+ err = 0;
+ break;
+ default:
+ err = EINVAL;
+ break;
+ }
+ return(err);
+}
+
+
#ifdef OSSV4_EXPERIMENT
/**
* @brief Retrieve an audio device's label

File Metadata

Mime Type
text/plain
Expires
Thu, Feb 19, 5:09 PM (4 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28885933
Default Alt Text
D53029.id163950.diff (4 KB)

Event Timeline