Author: jhb
Date: Wed Nov  6 19:33:25 2013
New Revision: 257759
URL: http://svnweb.freebsd.org/changeset/base/257759

Log:
  MFC 254072:
  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.

Modified:
  stable/9/sys/kern/kern_event.c
  stable/9/sys/sys/event.h
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/sys/   (props changed)

Modified: stable/9/sys/kern/kern_event.c
==============================================================================
--- stable/9/sys/kern/kern_event.c      Wed Nov  6 19:18:39 2013        
(r257758)
+++ stable/9/sys/kern/kern_event.c      Wed Nov  6 19:33:25 2013        
(r257759)
@@ -429,8 +429,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);
        }
 
@@ -1436,7 +1439,21 @@ start:
                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: stable/9/sys/sys/event.h
==============================================================================
--- stable/9/sys/sys/event.h    Wed Nov  6 19:18:39 2013        (r257758)
+++ stable/9/sys/sys/event.h    Wed Nov  6 19:33:25 2013        (r257759)
@@ -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 */
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "[email protected]"

Reply via email to