Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 7 Aug 2013 19:56:35 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r254072 - in head/sys: kern sys
Message-ID:  <201308071956.r77JuZWR068952@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Wed Aug  7 19:56:35 2013
New Revision: 254072
URL: http://svnweb.freebsd.org/changeset/base/254072

Log:
  Don't emit a spurious EVFILT_PROC event with no fflags set on process exit
  if NOTE_EXIT is not being monitored.  The rationale is that a listener
  should only get an event for exit() if they registered interest via
  NOTE_EXIT.  This matches the behavior on OS X.
  - Don't save the exit status on process exit unless NOTE_EXIT is being
    monitored.
  - Add an internal EV_DROP flag that requests kqueue_scan() to free the
    knote without signalling it to userland and use this when a process
    exits but the fflags in the knote is zero.
  
  Reviewed by:	jmg
  MFC after:	1 month

Modified:
  head/sys/kern/kern_event.c
  head/sys/sys/event.h

Modified: head/sys/kern/kern_event.c
==============================================================================
--- head/sys/kern/kern_event.c	Wed Aug  7 19:53:41 2013	(r254071)
+++ head/sys/kern/kern_event.c	Wed Aug  7 19:56:35 2013	(r254072)
@@ -431,8 +431,11 @@ filt_proc(struct knote *kn, long hint)
 		if (!(kn->kn_status & KN_DETACHED))
 			knlist_remove_inevent(&p->p_klist, kn);
 		kn->kn_flags |= (EV_EOF | EV_ONESHOT);
-		kn->kn_data = p->p_xstat;
 		kn->kn_ptr.p_proc = NULL;
+		if (kn->kn_fflags & NOTE_EXIT)
+			kn->kn_data = p->p_xstat;
+		if (kn->kn_fflags == 0)
+			kn->kn_flags |= EV_DROP;
 		return (1);
 	}
 
@@ -1410,7 +1413,21 @@ retry:
 		KASSERT((kn->kn_status & KN_INFLUX) == 0,
 		    ("KN_INFLUX set when not suppose to be"));
 
-		if ((kn->kn_flags & EV_ONESHOT) == EV_ONESHOT) {
+		if ((kn->kn_flags & EV_DROP) == EV_DROP) {
+			kn->kn_status &= ~KN_QUEUED;
+			kn->kn_status |= KN_INFLUX;
+			kq->kq_count--;
+			KQ_UNLOCK(kq);
+			/*
+			 * We don't need to lock the list since we've marked
+			 * it _INFLUX.
+			 */
+			if (!(kn->kn_status & KN_DETACHED))
+				kn->kn_fop->f_detach(kn);
+			knote_drop(kn, td);
+			KQ_LOCK(kq);
+			continue;
+		} else if ((kn->kn_flags & EV_ONESHOT) == EV_ONESHOT) {
 			kn->kn_status &= ~KN_QUEUED;
 			kn->kn_status |= KN_INFLUX;
 			kq->kq_count--;

Modified: head/sys/sys/event.h
==============================================================================
--- head/sys/sys/event.h	Wed Aug  7 19:53:41 2013	(r254071)
+++ head/sys/sys/event.h	Wed Aug  7 19:56:35 2013	(r254072)
@@ -76,6 +76,7 @@ struct kevent {
 #define EV_DISPATCH	0x0080		/* disable event after reporting */
 
 #define EV_SYSFLAGS	0xF000		/* reserved by system */
+#define	EV_DROP		0x1000		/* note should be dropped */
 #define EV_FLAG1	0x2000		/* filter-specific flag */
 
 /* returned values */



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