Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 1 Feb 2012 14:34:52 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r230866 - head/sys/kern
Message-ID:  <201202011434.q11EYqCt091007@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Wed Feb  1 14:34:52 2012
New Revision: 230866
URL: http://svn.freebsd.org/changeset/base/230866

Log:
  Add kqueue support to /dev/klog.
  
  Submitted by:	Mateusz Guzik <mjguzik gmail com>
  PR:	  kern/156423
  MFC after:	1 weeks

Modified:
  head/sys/kern/subr_log.c

Modified: head/sys/kern/subr_log.c
==============================================================================
--- head/sys/kern/subr_log.c	Wed Feb  1 13:39:52 2012	(r230865)
+++ head/sys/kern/subr_log.c	Wed Feb  1 14:34:52 2012	(r230866)
@@ -59,6 +59,7 @@ 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);
 
@@ -69,9 +70,20 @@ static struct cdevsw log_cdevsw = {
 	.d_read =	logread,
 	.d_ioctl =	logioctl,
 	.d_poll =	logpoll,
+	.d_kqfilter =	logkqfilter,
 	.d_name =	"log",
 };
 
+static int	logkqread(struct knote *note, long hint);
+static void	logkqdetach(struct knote *note);
+
+static struct filterops log_read_filterops = {
+	.f_isfd =	1,
+	.f_attach =	NULL,
+	.f_detach =	logkqdetach,
+	.f_event =	logkqread,
+};
+
 static struct logsoftc {
 	int	sc_state;		/* see above for possibilities */
 	struct	selinfo sc_selp;	/* process waiting on select call */
@@ -181,6 +193,40 @@ logpoll(struct cdev *dev, int events, st
 	return (revents);
 }
 
+static int
+logkqfilter(struct cdev *dev, struct knote *kn)
+{
+
+	if (kn->kn_filter != EVFILT_READ)
+		return (EINVAL);
+
+	kn->kn_fop = &log_read_filterops;
+	kn->kn_hook = NULL;
+
+	mtx_lock(&msgbuf_lock);
+	knlist_add(&logsoftc.sc_selp.si_note, kn, 1);
+	mtx_unlock(&msgbuf_lock);
+	return (0);
+}
+
+static int
+logkqread(struct knote *kn, long hint)
+{
+
+	mtx_assert(&msgbuf_lock, MA_OWNED);
+	kn->kn_data = msgbuf_getcount(msgbufp);
+	return (kn->kn_data != 0);
+}
+
+static void
+logkqdetach(struct knote *kn)
+{
+
+	mtx_lock(&msgbuf_lock);
+	knlist_remove(&logsoftc.sc_selp.si_note, kn, 1);
+	mtx_unlock(&msgbuf_lock);
+}
+
 static void
 logtimeout(void *arg)
 {
@@ -198,6 +244,7 @@ logtimeout(void *arg)
 	}
 	msgbuftrigger = 0;
 	selwakeuppri(&logsoftc.sc_selp, LOG_RDPRI);
+	KNOTE_LOCKED(&logsoftc.sc_selp.si_note, 0);
 	if ((logsoftc.sc_state & LOG_ASYNC) && logsoftc.sc_sigio != NULL)
 		pgsigio(&logsoftc.sc_sigio, SIGIO, 0);
 	cv_broadcastpri(&log_wakeup, LOG_RDPRI);
@@ -256,6 +303,7 @@ log_drvinit(void *unused)
 
 	cv_init(&log_wakeup, "klog");
 	callout_init_mtx(&logsoftc.sc_callout, &msgbuf_lock, 0);
+	knlist_init_mtx(&logsoftc.sc_selp.si_note, &msgbuf_lock);
 	make_dev_credf(MAKEDEV_ETERNAL, &log_cdevsw, 0, NULL, UID_ROOT,
 	    GID_WHEEL, 0600, "klog");
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202011434.q11EYqCt091007>