[Bug 203366] kevent: EV_CLEAR on fifo does not work correctly

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Thu Feb 15 19:15:24 UTC 2018


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=203366

--- Comment #9 from Bryan Drewery <bdrewery at FreeBSD.org> ---
r232055 dropped the fifo filter:
-static int
-filt_fiforead(struct knote *kn, long hint)
-{
-       struct socket *so = (struct socket *)kn->kn_hook;
-
-       SOCKBUF_LOCK_ASSERT(&so->so_rcv);
-       kn->kn_data = so->so_rcv.sb_cc;
-       if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
-               kn->kn_flags |= EV_EOF;
-               return (1);
-       } else {
-               kn->kn_flags &= ~EV_EOF;
-               return (kn->kn_data > 0);
-       }
-}

in fifo_open (for writer) this change was made:
                if (fip->fi_writers == 1) {
-                       SOCKBUF_LOCK(&fip->fi_readsock->so_rcv);
-                       fip->fi_readsock->so_rcv.sb_state &= ~SBS_CANTRCVMORE;
-                       SOCKBUF_UNLOCK(&fip->fi_readsock->so_rcv);
-                       if (fip->fi_readers > 0) {
+                       fpipe->pipe_state &= ~PIPE_EOF;
+                       if (fip->fi_readers > 0)
                                wakeup(&fip->fi_readers);
-                               sorwakeup(fip->fi_readsock);
-                       }

The filter used is:
static int                                                           
filt_piperead(struct knote *kn, long hint)                           
{                                                                    
        struct pipe *rpipe = kn->kn_hook;                            
        struct pipe *wpipe = rpipe->pipe_peer;                       
        int ret;                                                     

        PIPE_LOCK_ASSERT(rpipe, MA_OWNED);                           
        kn->kn_data = rpipe->pipe_buffer.cnt;                        
        if ((kn->kn_data == 0) && (rpipe->pipe_state & PIPE_DIRECTW))
                kn->kn_data = rpipe->pipe_map.cnt;                   

        if ((rpipe->pipe_state & PIPE_EOF) ||                        
            wpipe->pipe_present != PIPE_ACTIVE ||                    
            (wpipe->pipe_state & PIPE_EOF)) {                        
                kn->kn_flags |= EV_EOF;                              
                return (1);                                          
        }                                                            
        ret = kn->kn_data > 0;                                       
        return ret;                                                  
}                                                                    

So it seems we just need to clear EV_EOF again if PIPE_EOF is not set.

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-bugs mailing list