From: Samuel J. Greear Date: Tue, 15 Jun 2010 16:44:44 +0000 (+0000) Subject: kernel - Add kqueue to log device (/dev/klog) X-Git-Tag: v2.9.0~690^2~63 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/fef8f01a63adb168dd043d0e835694b0d02c59c9 kernel - Add kqueue to log device (/dev/klog) --- diff --git a/sys/kern/subr_log.c b/sys/kern/subr_log.c index e6b4fa57bd..d5ab5b5f2e 100644 --- a/sys/kern/subr_log.c +++ b/sys/kern/subr_log.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -63,17 +64,21 @@ static d_close_t logclose; static d_read_t logread; static d_ioctl_t logioctl; static d_poll_t logpoll; +static d_kqfilter_t logkqfilter; static void logtimeout(void *arg); +static void logfiltdetach(struct knote *kn); +static int logfiltread(struct knote *kn, long hint); #define CDEV_MAJOR 7 static struct dev_ops log_ops = { - { "log", CDEV_MAJOR, 0 }, + { "log", CDEV_MAJOR, D_KQFILTER }, .d_open = logopen, .d_close = logclose, .d_read = logread, .d_ioctl = logioctl, .d_poll = logpoll, + .d_kqfilter = logkqfilter }; static struct logsoftc { @@ -178,6 +183,55 @@ logpoll(struct dev_poll_args *ap) return (0); } +static struct filterops logread_filtops = + { 1, NULL, logfiltdetach, logfiltread }; + +static int +logkqfilter(struct dev_kqfilter_args *ap) +{ + struct knote *kn = ap->a_kn; + struct klist *klist = &logsoftc.sc_selp.si_note; + + ap->a_result = 0; + switch (kn->kn_filter) { + case EVFILT_READ: + kn->kn_fop = &logread_filtops; + break; + default: + ap->a_result = 1; + return (0); + } + + crit_enter(); + SLIST_INSERT_HEAD(klist, kn, kn_selnext); + crit_exit(); + + return (0); +} + +static void +logfiltdetach(struct knote *kn) +{ + struct klist *klist = &logsoftc.sc_selp.si_note; + + crit_enter(); + SLIST_REMOVE(klist, kn, knote, kn_selnext); + crit_exit(); +} + +static int +logfiltread(struct knote *kn, long hint) +{ + int ret = 0; + + crit_enter(); + if (msgbufp->msg_bufr != msgbufp->msg_bufx) + ret = 1; + crit_exit(); + + return (ret); +} + static void logtimeout(void *arg) {