about summary refs log tree commit diff
path: root/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c
diff options
context:
space:
mode:
Diffstat (limited to 'rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c')
-rw-r--r--rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c50
1 files changed, 43 insertions, 7 deletions
diff --git a/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c b/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c
index 0b3380f98a..2400c5223c 100644
--- a/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c
+++ b/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c
@@ -1,5 +1,6 @@
 /* Suspend until termination of a requests.
-   Copyright (C) 1997,1998,1999,2000,2002,2003 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2006
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -37,8 +38,10 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <sys/time.h>
+
 #include <bits/libc-lock.h>
 #include <sysdep-cancel.h>
 
@@ -48,7 +51,9 @@ struct clparam
   const struct aiocb *const *list;
   struct waitlist *waitlist;
   struct requestlist **requestlist;
+#ifndef DONT_NEED_AIO_MISC_COND
   pthread_cond_t *cond;
+#endif
   int nent;
 };
 
@@ -56,6 +61,12 @@ struct clparam
 static void
 cleanup (void *arg)
 {
+#ifdef DONT_NEED_AIO_MISC_COND
+  /* Acquire the mutex.  If pthread_cond_*wait is used this would
+     happen implicitly.  */
+  pthread_mutex_lock (&__aio_requests_mutex);
+#endif
+
   const struct clparam *param = (const struct clparam *) arg;
 
   /* Now remove the entry in the waiting list for all requests
@@ -79,8 +90,10 @@ cleanup (void *arg)
 	  *listp = (*listp)->next;
       }
 
+#ifndef DONT_NEED_AIO_MISC_COND
   /* Release the conditional variable.  */
   (void) pthread_cond_destroy (param->cond);
+#endif
 
   /* Release the mutex.  */
   pthread_mutex_unlock (&__aio_requests_mutex);
@@ -93,11 +106,20 @@ aio_suspend (list, nent, timeout)
      int nent;
      const struct timespec *timeout;
 {
+  if (__builtin_expect (nent < 0, 0))
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
   struct waitlist waitlist[nent];
   struct requestlist *requestlist[nent];
+#ifndef DONT_NEED_AIO_MISC_COND
   pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+#endif
   int cnt;
   int result = 0;
+  int cntr = 1;
   int total = 0, ktotal = 0;
 
   /* Request the mutex.  */
@@ -114,9 +136,12 @@ aio_suspend (list, nent, timeout)
 
 	    if (requestlist[cnt] != NULL)
 	      {
+#ifndef DONT_NEED_AIO_MISC_COND
 		waitlist[cnt].cond = &cond;
+#endif
+		waitlist[cnt].result = NULL;
 		waitlist[cnt].next = requestlist[cnt]->waiting;
-		waitlist[cnt].counterp = &total;
+		waitlist[cnt].counterp = &cntr;
 		waitlist[cnt].sigevp = NULL;
 #ifdef BROKEN_THREAD_SIGNALS
 		waitlist[cnt].caller_pid = 0;	/* Not needed.  */
@@ -144,13 +169,15 @@ aio_suspend (list, nent, timeout)
 	  .list = list,
 	  .waitlist = waitlist,
 	  .requestlist = requestlist,
+#ifndef DONT_NEED_AIO_MISC_COND
 	  .cond = &cond,
+#endif
 	  .nent = nent
 	};
 
       pthread_cleanup_push (cleanup, &clparam);
 
-      if (!__kernel_thread_started)
+      if (!__kernel_thread_started && ktotal)
 	{
 	  /* If the kernel aio thread was not started yet all requests
 	     are served by the kernel and there are no other threads running,
@@ -160,7 +187,7 @@ aio_suspend (list, nent, timeout)
 	    {
 	      if (timeout == NULL)
 		{
-		  while (total == ktotal)
+		  while (cntr == 1)
 		    __aio_wait_for_events (__aio_kioctx, NULL);
 		}
 	      else
@@ -180,7 +207,7 @@ aio_suspend (list, nent, timeout)
 		  for (;;)
 		    {
 		      result = __aio_wait_for_events (__aio_kioctx, timeout);
-		      if (total < ktotal)
+		      if (cntr < 1)
 			break;
 		      if (result == ETIMEDOUT)
 			break;
@@ -201,7 +228,7 @@ aio_suspend (list, nent, timeout)
 		      timeout = &ts;
 		    }
 
-		  if (total < ktotal)
+		  if (cntr < 1)
 		    result = 0;
 		  else
 		    result = ETIMEDOUT;
@@ -219,6 +246,10 @@ aio_suspend (list, nent, timeout)
       if (total == 0)
 	/* Suspending was handled above.  */
 	;
+#ifdef DONT_NEED_AIO_MISC_COND
+      else
+	AIO_MISC_WAIT (result, cntr, timeout, 1);
+#else
       else if (timeout == NULL)
 	result = pthread_cond_wait (&cond, &__aio_requests_mutex);
       else
@@ -240,6 +271,7 @@ aio_suspend (list, nent, timeout)
 	  result = pthread_cond_timedwait (&cond, &__aio_requests_mutex,
 					   &abstime);
 	}
+#endif
 
       pthread_cleanup_pop (0);
     }
@@ -263,19 +295,23 @@ aio_suspend (list, nent, timeout)
 	  *listp = (*listp)->next;
       }
 
+#ifndef DONT_NEED_AIO_MISC_COND
   /* Release the conditional variable.  */
   if (__builtin_expect (pthread_cond_destroy (&cond) != 0, 0))
     /* This must never happen.  */
     abort ();
+#endif
 
   if (result != 0)
     {
-      /* An error occurred.  Possibly it's EINTR.  We have to translate
+#ifndef DONT_NEED_AIO_MISC_COND
+      /* An error occurred.  Possibly it's ETIMEDOUT.  We have to translate
 	 the timeout error report of `pthread_cond_timedwait' to the
 	 form expected from `aio_suspend'.  */
       if (result == ETIMEDOUT)
 	__set_errno (EAGAIN);
       else
+#endif
 	__set_errno (result);
 
       result = -1;