The following reply was made to PR kern/143029; it has been noted by GNATS.

From: dfil...@freebsd.org (dfilter service)
To: bug-follo...@freebsd.org
Cc:  
Subject: Re: kern/143029: commit references a PR
Date: Sat, 28 Aug 2010 17:42:22 +0000 (UTC)

 Author: kib
 Date: Sat Aug 28 17:42:08 2010
 New Revision: 211941
 URL: http://svn.freebsd.org/changeset/base/211941
 
 Log:
   For some file types, select code registers two selfd structures. E.g.,
   for socket, when specified POLLIN|POLLOUT in events, you would have one
   selfd registered for receiving socket buffer, and one for sending. Now,
   if both events are not ready to fire at the time of the initial scan,
   but are simultaneously ready after the sleep, pollrescan() would iterate
   over the pollfd struct twice. Since both times revents is not zero,
   returned value would be off by one.
   
   Fix this by recalculating the return value in pollout().
   
   PR:  kern/143029
   MFC after:   2 weeks
 
 Modified:
   head/sys/kern/sys_generic.c
 
 Modified: head/sys/kern/sys_generic.c
 ==============================================================================
 --- head/sys/kern/sys_generic.c        Sat Aug 28 17:38:40 2010        
(r211940)
 +++ head/sys/kern/sys_generic.c        Sat Aug 28 17:42:08 2010        
(r211941)
 @@ -76,7 +76,8 @@ static MALLOC_DEFINE(M_IOCTLOPS, "ioctlo
  static MALLOC_DEFINE(M_SELECT, "select", "select() buffer");
  MALLOC_DEFINE(M_IOV, "iov", "large iov's");
  
 -static int    pollout(struct pollfd *, struct pollfd *, u_int);
 +static int    pollout(struct thread *, struct pollfd *, struct pollfd *,
 +                  u_int);
  static int    pollscan(struct thread *, struct pollfd *, u_int);
  static int    pollrescan(struct thread *);
  static int    selscan(struct thread *, fd_mask **, fd_mask **, int);
 @@ -1207,7 +1208,7 @@ done:
        if (error == EWOULDBLOCK)
                error = 0;
        if (error == 0) {
 -              error = pollout(bits, uap->fds, nfds);
 +              error = pollout(td, bits, uap->fds, nfds);
                if (error)
                        goto out;
        }
 @@ -1262,22 +1263,27 @@ pollrescan(struct thread *td)
  
  
  static int
 -pollout(fds, ufds, nfd)
 +pollout(td, fds, ufds, nfd)
 +      struct thread *td;
        struct pollfd *fds;
        struct pollfd *ufds;
        u_int nfd;
  {
        int error = 0;
        u_int i = 0;
 +      u_int n = 0;
  
        for (i = 0; i < nfd; i++) {
                error = copyout(&fds->revents, &ufds->revents,
                    sizeof(ufds->revents));
                if (error)
                        return (error);
 +              if (fds->revents != 0)
 +                      n++;
                fds++;
                ufds++;
        }
 +      td->td_retval[0] = n;
        return (0);
  }
  
 _______________________________________________
 svn-src-...@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
 
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to