From c86410c6ffb0193e510fcc9990b1ebb6205c47e3 Mon Sep 17 00:00:00 2001
From: Peter S. Mazinger <ps.m@gmx.net>
Date: Thu, 21 Apr 2011 23:16:19 +0200
Subject: [PATCH 323/396] pselect.c: avoid handling cancellation twice

Use __select_nocancel instead of select

Signed-off-by: Peter S. Mazinger <ps.m@gmx.net>
---
 libc/sysdeps/linux/common/pselect.c |  107 +++++++++++++----------------------
 1 files changed, 39 insertions(+), 68 deletions(-)

diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c
index 7e93537..d89b7b4 100644
--- a/libc/sysdeps/linux/common/pselect.c
+++ b/libc/sysdeps/linux/common/pselect.c
@@ -17,78 +17,49 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <errno.h>
-#include <signal.h>
-#include <stddef.h>	/* For NULL.  */
-#include <sys/time.h>
-#include <sys/select.h>
-#ifdef __UCLIBC_HAS_THREADS_NATIVE__
-#include <sysdep-cancel.h>
-#endif
+#include <features.h>
 
-libc_hidden_proto(sigprocmask)
-libc_hidden_proto(select)
+#ifdef __USE_XOPEN2K
 
+#include <sys/syscall.h>
+#include <sys/select.h>
+#include <signal.h>
+#include <cancel.h>
 
-/* Check the first NFDS descriptors each in READFDS (if not NULL) for read
-   readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS
-   (if not NULL) for exceptional conditions.  If TIMEOUT is not NULL, time out
-   after waiting the interval specified therein.  Additionally set the sigmask
-   SIGMASK for this call.  Returns the number of ready descriptors, or -1 for
-   errors.  */
-#ifdef __UCLIBC_HAS_THREADS_NATIVE__
-static int
-__pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
-#else
-int
-pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
-#endif
-	   const struct timespec *timeout, const sigset_t *sigmask)
+static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds,
+			 fd_set *exceptfds, const struct timespec *timeout,
+			 const sigset_t *sigmask)
 {
-  struct timeval tval;
-  int retval;
-  sigset_t savemask;
-
-  /* Change nanosecond number to microseconds.  This might mean losing
-     precision and therefore the `pselect` should be available.  But
-     for now it is hardly found.  */
-  if (timeout != NULL)
-    TIMESPEC_TO_TIMEVAL (&tval, timeout);
-
-  /* The setting and restoring of the signal mask and the select call
-     should be an atomic operation.  This can't be done without kernel
-     help.  */
-  if (sigmask != NULL)
-    sigprocmask (SIG_SETMASK, sigmask, &savemask);
-
-  /* Note the pselect() is a cancellation point.  But since we call
-     select() which itself is a cancellation point we do not have
-     to do anything here.  */
-  retval = select (nfds, readfds, writefds, exceptfds,
-		     timeout != NULL ? &tval : NULL);
-
-  if (sigmask != NULL)
-    sigprocmask (SIG_SETMASK, &savemask, NULL);
-
-  return retval;
+	struct timeval tval;
+	int retval;
+	sigset_t savemask;
+
+	/* Change nanosecond number to microseconds.  This might mean losing
+	   precision and therefore the `pselect` should be available.  But
+	   for now it is hardly found.  */
+	if (timeout != NULL)
+		TIMESPEC_TO_TIMEVAL (&tval, timeout);
+
+	/* The setting and restoring of the signal mask and the select call
+	   should be an atomic operation.  This can't be done without kernel
+	   help.  */
+	if (sigmask != NULL)
+		sigprocmask (SIG_SETMASK, sigmask, &savemask);
+
+	/* The comment below does not apply on uClibc, since we use __select_nocancel */
+	/* Note the pselect() is a cancellation point.  But since we call
+	   select() which itself is a cancellation point we do not have
+	   to do anything here.  */
+	retval = __NC(select)(nfds, readfds, writefds, exceptfds,
+			timeout != NULL ? &tval : NULL);
+
+	if (sigmask != NULL)
+		sigprocmask (SIG_SETMASK, &savemask, NULL);
+
+	return retval;
 }
+CANCELLABLE_SYSCALL(int, pselect, (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+				   const struct timespec *timeout, const sigset_t *sigmask),
+		    (nfds, readfds, writefds, exceptfds, timeout, sigmask))
 
-#ifdef __UCLIBC_HAS_THREADS_NATIVE__
-int
-pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
-	   const struct timespec *timeout, const sigset_t *sigmask)
-{
-	if (SINGLE_THREAD_P)
-		return __pselect (nfds, readfds, writefds, exceptfds,
-				  timeout, sigmask);
-
-	int oldtype = LIBC_CANCEL_ASYNC ();
-
-	int result = __pselect (nfds, readfds, writefds, exceptfds,
-				 timeout, sigmask);
-
-	LIBC_CANCEL_RESET (oldtype);
-
-	return result;
-}
 #endif
-- 
1.7.0.4

