From owner-svn-src-all@FreeBSD.ORG Sat Aug 28 17:42:08 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DA8011065672; Sat, 28 Aug 2010 17:42:08 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id AFD828FC12; Sat, 28 Aug 2010 17:42:08 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o7SHg8Yw038630; Sat, 28 Aug 2010 17:42:08 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o7SHg8gZ038628; Sat, 28 Aug 2010 17:42:08 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201008281742.o7SHg8gZ038628@svn.freebsd.org> From: Konstantin Belousov Date: Sat, 28 Aug 2010 17:42:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r211941 - head/sys/kern X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 28 Aug 2010 17:42:08 -0000 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); }