Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Mar 2009 22:00:03 +0000 (UTC)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r189708 - head/sys/kern
Message-ID:  <200903112200.n2BM03Q2007742@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rwatson
Date: Wed Mar 11 22:00:03 2009
New Revision: 189708
URL: http://svn.freebsd.org/changeset/base/189708

Log:
  When writing out updated pollfd records when returning from
  poll(), only copy out the revents field, not the whole pollfd
  structure.  Otherwise, if the events field is updated
  concurrently by another thread, that update may be lost.
  
  This issue apparently causes problems for the JDK on FreeBSD,
  which expects the Linux behavior of not updating all fields
  (somewhat oddly, Solaris does not implement the required
  behavior, but presumably our adaptation of the JDK is based
  on the Linux port?).
  
  MFC after:      2 weeks
  PR:		kern/130924
  Submitted by:   Kurt Miller <kurt @ intricatesoftware.com>
  Discussed with:	kib

Modified:
  head/sys/kern/sys_generic.c

Modified: head/sys/kern/sys_generic.c
==============================================================================
--- head/sys/kern/sys_generic.c	Wed Mar 11 21:48:36 2009	(r189707)
+++ head/sys/kern/sys_generic.c	Wed Mar 11 22:00:03 2009	(r189708)
@@ -76,6 +76,7 @@ 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	pollscan(struct thread *, struct pollfd *, u_int);
 static int	pollrescan(struct thread *);
 static int	selscan(struct thread *, fd_mask **, fd_mask **, int);
@@ -1128,7 +1129,7 @@ done:
 	if (error == EWOULDBLOCK)
 		error = 0;
 	if (error == 0) {
-		error = copyout(bits, uap->fds, ni);
+		error = pollout(bits, uap->fds, nfds);
 		if (error)
 			goto out;
 	}
@@ -1183,6 +1184,26 @@ pollrescan(struct thread *td)
 
 
 static int
+pollout(fds, ufds, nfd)
+	struct pollfd *fds;
+	struct pollfd *ufds;
+	u_int nfd;
+{
+	int error = 0;
+	u_int i = 0;
+
+	for (i = 0; i < nfd; i++) {
+		error = copyout(&fds->revents, &ufds->revents,
+		    sizeof(ufds->revents));
+		if (error)
+			return (error);
+		fds++;
+		ufds++;
+	}
+	return (0);
+}
+
+static int
 pollscan(td, fds, nfd)
 	struct thread *td;
 	struct pollfd *fds;



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