Browse Source

pselect.c: avoid handling cancellation twice

Use __select_nocancel instead of select

Signed-off-by: Peter S. Mazinger <ps.m@gmx.net>
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Peter S. Mazinger 13 years ago
parent
commit
551ca52892
1 changed files with 40 additions and 68 deletions
  1. 40 68
      libc/sysdeps/linux/common/pselect.c

+ 40 - 68
libc/sysdeps/linux/common/pselect.c

@@ -17,78 +17,50 @@
    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 <sys/time.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