svn commit: r197241 - in head: lib/libc/sys sys/kern sys/sys

Stacey Son sson at FreeBSD.org
Wed Sep 16 03:30:12 UTC 2009


Author: sson
Date: Wed Sep 16 03:30:12 2009
New Revision: 197241
URL: http://svn.freebsd.org/changeset/base/197241

Log:
  Add EVFILT_USER to kevents.
  
  Add user events support to kernel events which are not associated with any
  kernel mechanism but are triggered by user level code.  This is useful for
  adding user level events to an event handler that may also be monitoring
  kernel events.
  
  Approved by:	rwatson (co-mentor)

Modified:
  head/lib/libc/sys/kqueue.2
  head/sys/kern/kern_event.c
  head/sys/sys/event.h

Modified: head/lib/libc/sys/kqueue.2
==============================================================================
--- head/lib/libc/sys/kqueue.2	Wed Sep 16 03:15:57 2009	(r197240)
+++ head/lib/libc/sys/kqueue.2	Wed Sep 16 03:30:12 2009	(r197241)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd September 6, 2007
+.Dd September 15, 2009
 .Dt KQUEUE 2
 .Os
 .Sh NAME
@@ -441,6 +441,44 @@ The link state is invalid.
 On return,
 .Va fflags
 contains the events which triggered the filter.
+.It Dv EVFILT_USER
+Establishes a user event identified by
+.Va ident
+which is not assosicated with any kernel mechanism but is triggered by
+user level code.
+The lower 24 bits of the 
+.Va fflags
+may be used for user defined flags and manipulated using the following:
+.Bl -tag -width XXNOTE_FFLAGSMASK 
+.It Dv NOTE_FFNOP
+Ignore the input
+.Va fflags .
+.It Dv NOTE_FFAND
+Bitwise AND
+.Va fflags .
+.It Dv NOTE_FFOR
+Bitwise OR
+.Va fflags .
+.It Dv NOTE_COPY
+Copy
+.Va fflags .
+.It Dv NOTE_FFCTRLMASK
+Control mask for
+.Va fflags .
+.It Dv NOTE_FFLAGSMASK
+User defined flag mask for
+.Va fflags .
+.El
+.Pp
+A user event is triggered for output with the following:
+.Bl -tag -width XXNOTE_FFLAGSMASK
+.It Dv NOTE_TRIGGER
+Cause the event to be triggered.
+.El
+.Pp
+On return,
+.Va fflags
+contains the users defined flags in the lower 24 bits.
 .El
 .Sh RETURN VALUES
 The

Modified: head/sys/kern/kern_event.c
==============================================================================
--- head/sys/kern/kern_event.c	Wed Sep 16 03:15:57 2009	(r197240)
+++ head/sys/kern/kern_event.c	Wed Sep 16 03:30:12 2009	(r197241)
@@ -142,6 +142,10 @@ static void	filt_timerexpire(void *knx);
 static int	filt_timerattach(struct knote *kn);
 static void	filt_timerdetach(struct knote *kn);
 static int	filt_timer(struct knote *kn, long hint);
+static int	filt_userattach(struct knote *kn);
+static void	filt_userdetach(struct knote *kn);
+static int	filt_user(struct knote *kn, long hint);
+static void	filt_usertouch(struct knote *kn, struct kevent *kev, long type);
 
 static struct filterops file_filtops = {
 	.f_isfd = 1,
@@ -165,6 +169,12 @@ static struct filterops timer_filtops = 
 	.f_detach = filt_timerdetach,
 	.f_event = filt_timer,
 };
+static struct filterops user_filtops = {
+	.f_attach = filt_userattach,
+	.f_detach = filt_userdetach,
+	.f_event = filt_user,
+	.f_touch = filt_usertouch,
+};
 
 static uma_zone_t	knote_zone;
 static int 		kq_ncallouts = 0;
@@ -271,6 +281,7 @@ static struct {
 	{ &file_filtops },			/* EVFILT_NETDEV */
 	{ &fs_filtops },			/* EVFILT_FS */
 	{ &null_filtops },			/* EVFILT_LIO */
+	{ &user_filtops },			/* EVFILT_USER */
 };
 
 /*
@@ -573,6 +584,94 @@ filt_timer(struct knote *kn, long hint)
 	return (kn->kn_data != 0);
 }
 
+static int
+filt_userattach(struct knote *kn)
+{
+
+	/* 
+	 * EVFILT_USER knotes are not attached to anything in the kernel.
+	 */ 
+	kn->kn_hook = NULL;
+	if (kn->kn_fflags & NOTE_TRIGGER)
+		kn->kn_hookid = 1;
+	else
+		kn->kn_hookid = 0;
+	return (0);
+}
+
+static void
+filt_userdetach(__unused struct knote *kn)
+{
+
+	/*
+	 * EVFILT_USER knotes are not attached to anything in the kernel.
+	 */
+}
+
+static int
+filt_user(struct knote *kn, __unused long hint)
+{
+
+	return (kn->kn_hookid);
+}
+
+static void
+filt_usertouch(struct knote *kn, struct kevent *kev, long type)
+{
+	int ffctrl;
+
+	switch (type) {
+	case EVENT_REGISTER:
+		if (kev->fflags & NOTE_TRIGGER)
+			kn->kn_hookid = 1;
+
+		ffctrl = kev->fflags & NOTE_FFCTRLMASK;
+		kev->fflags &= NOTE_FFLAGSMASK;
+		switch (ffctrl) {
+		case NOTE_FFNOP:
+			break;
+
+		case NOTE_FFAND:
+			kn->kn_sfflags &= kev->fflags;
+			break;
+
+		case NOTE_FFOR:
+			kn->kn_sfflags |= kev->fflags;
+			break;
+
+		case NOTE_FFCOPY:
+			kn->kn_sfflags = kev->fflags;
+			break;
+
+		default:
+			/* XXX Return error? */
+			break;
+		}
+		kn->kn_sdata = kev->data;
+		if (kev->flags & EV_CLEAR) {
+			kn->kn_hookid = 0;
+			kn->kn_data = 0;
+			kn->kn_fflags = 0;
+		}
+		break;
+
+        case EVENT_PROCESS:
+		*kev = kn->kn_kevent;
+		kev->fflags = kn->kn_sfflags;
+		kev->data = kn->kn_sdata;
+		if (kn->kn_flags & EV_CLEAR) {
+			kn->kn_hookid = 0;
+			kn->kn_data = 0;
+			kn->kn_fflags = 0;
+		}
+		break;
+
+	default:
+		panic("filt_usertouch() - invalid type (%ld)", type);
+		break;
+	}
+}
+
 int
 kqueue(struct thread *td, struct kqueue_args *uap)
 {

Modified: head/sys/sys/event.h
==============================================================================
--- head/sys/sys/event.h	Wed Sep 16 03:15:57 2009	(r197240)
+++ head/sys/sys/event.h	Wed Sep 16 03:30:12 2009	(r197241)
@@ -41,7 +41,8 @@
 #define EVFILT_NETDEV		(-8)	/* network devices */
 #define EVFILT_FS		(-9)	/* filesystem events */
 #define EVFILT_LIO		(-10)	/* attached to lio requests */
-#define EVFILT_SYSCOUNT		10
+#define EVFILT_USER		(-11)	/* User events */
+#define EVFILT_SYSCOUNT		11
 
 #define EV_SET(kevp_, a, b, c, d, e, f) do {	\
 	struct kevent *kevp = (kevp_);		\
@@ -79,6 +80,25 @@ struct kevent {
 #define EV_EOF		0x8000		/* EOF detected */
 #define EV_ERROR	0x4000		/* error, data contains errno */
 
+ /*
+  * data/hint flags/masks for EVFILT_USER, shared with userspace
+  *
+  * On input, the top two bits of fflags specifies how the lower twenty four
+  * bits should be applied to the stored value of fflags.
+  *
+  * On output, the top two bits will always be set to NOTE_FFNOP and the
+  * remaining twenty four bits will contain the stored fflags value.
+  */
+#define NOTE_FFNOP	0x00000000		/* ignore input fflags */
+#define NOTE_FFAND	0x40000000		/* AND fflags */
+#define NOTE_FFOR	0x80000000		/* OR fflags */
+#define NOTE_FFCOPY	0xc0000000		/* copy fflags */
+#define NOTE_FFCTRLMASK	0xc0000000		/* masks for operations */
+#define NOTE_FFLAGSMASK	0x00ffffff
+
+#define NOTE_TRIGGER	0x01000000		/* Cause the event to be
+						   triggered for output. */
+
 /*
  * data/hint flags for EVFILT_{READ|WRITE}, shared with userspace
  */


More information about the svn-src-all mailing list