OSDN Git Service

Change pthread::cancelable_wait to just cancelable_wait, throughout.
authorcgf <cgf>
Thu, 9 Jun 2005 05:11:50 +0000 (05:11 +0000)
committercgf <cgf>
Thu, 9 Jun 2005 05:11:50 +0000 (05:11 +0000)
* thread.h (cw_sig_wait): New enum.
(fast_mutex::lock): Use cancelable_wait with resumable signal.
(cancelable_wait): Change fourth argument to cw_sig_wait enum.
* thread.cc (cancelable_wait): Ditto.  Loop on signal detection if fourth
argument == cw_sig_resume.

winsup/cygwin/ChangeLog
winsup/cygwin/exceptions.cc
winsup/cygwin/signal.cc
winsup/cygwin/thread.cc
winsup/cygwin/thread.h
winsup/cygwin/wait.cc

index f7c908c..6b0a04d 100644 (file)
@@ -1,3 +1,12 @@
+2005-06-09  Christopher Faylor  <cgf@timesys.com>
+
+       Change pthread::cancelable_wait to just cancelable_wait, throughout.
+       * thread.h (cw_sig_wait): New enum.
+       (fast_mutex::lock): Use cancelable_wait with resumable signal.
+       (cancelable_wait): Change fourth argument to cw_sig_wait enum.
+       * thread.cc (cancelable_wait): Ditto.  Loop on signal detection if
+       fourth argument == cw_sig_resume.
+
 2005-06-08  Christopher Faylor  <cgf@timesys.com>
 
        * cygwin.sc: Apparently nonloading sections need to go last.
index b886e34..6e44b5b 100644 (file)
@@ -574,7 +574,7 @@ handle_sigsuspend (sigset_t tempmask)
   sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
 
   pthread_testcancel ();
-  pthread::cancelable_wait (signal_arrived, INFINITE);
+  cancelable_wait (signal_arrived, INFINITE);
 
   set_sig_errno (EINTR);       // Per POSIX
 
index 1808b24..935083c 100644 (file)
@@ -88,7 +88,7 @@ nanosleep (const struct timespec *rqtp, struct timespec *rmtp)
   DWORD end_time = gtod.dmsecs () + req;
   syscall_printf ("nanosleep (%ld)", req);
 
-  int rc = pthread::cancelable_wait (signal_arrived, req);
+  int rc = cancelable_wait (signal_arrived, req);
   DWORD rem;
   if ((rem = end_time - gtod.dmsecs ()) > HIRES_DELAY_MAX)
     rem = 0;
index e2ffe8e..9a3c7af 100644 (file)
@@ -604,13 +604,13 @@ pthread::static_cancel_self (void)
 }
 
 DWORD
-pthread::cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel,
-                         const bool do_sig_wait)
+cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel,
+                const enum cw_sig_wait sig_wait)
 {
   DWORD res;
   DWORD num = 0;
   HANDLE wait_objects[3];
-  pthread_t thread = self ();
+  pthread_t thread = pthread::self ();
 
   /* Do not change the wait order.
      The object must have higher priority than the cancel event,
@@ -618,7 +618,7 @@ pthread::cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel,
      if both objects are signaled. */
   wait_objects[num++] = object;
   DWORD cancel_n;
-  if (!is_good_object (&thread) ||
+  if (!pthread::is_good_object (&thread) ||
       thread->cancelstate == PTHREAD_CANCEL_DISABLE)
     cancel_n = (DWORD) -1;
   else
@@ -628,7 +628,7 @@ pthread::cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel,
     }
 
   DWORD sig_n;
-  if (!do_sig_wait || &_my_tls != _main_tls)
+  if (sig_wait == cw_sig_nosig || &_my_tls != _main_tls)
     sig_n = (DWORD) -1;
   else
     {
@@ -636,14 +636,26 @@ pthread::cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel,
       wait_objects[sig_n] = signal_arrived;
     }
 
-  res = WaitForMultipleObjects (num, wait_objects, FALSE, timeout);
-  if (res == sig_n - WAIT_OBJECT_0)
-    res = WAIT_SIGNALED;
-  else if (res == cancel_n - WAIT_OBJECT_0)
+  while (1)
     {
-      if (do_cancel)
-       pthread::static_cancel_self ();
-      res = WAIT_CANCELED;
+      res = WaitForMultipleObjects (num, wait_objects, FALSE, timeout);
+      res -= WAIT_OBJECT_0;
+      if (res == cancel_n)
+       {
+         if (do_cancel)
+           pthread::static_cancel_self ();
+         res = WAIT_CANCELED;
+       }
+      else if (res != sig_n)
+       /* all set */;
+      else if (sig_wait == cw_sig_eintr)
+       res = WAIT_SIGNALED;
+      else
+       {
+         _my_tls.call_signal_handler ();
+         continue;
+       }
+      break;
     }
   return res;
 }
@@ -943,7 +955,7 @@ pthread_cond::wait (pthread_mutex_t mutex, DWORD dwMilliseconds)
   ++mutex->condwaits;
   mutex->unlock ();
 
-  rv = pthread::cancelable_wait (sem_wait, dwMilliseconds, false, true);
+  rv = cancelable_wait (sem_wait, dwMilliseconds, false, cw_sig_eintr);
 
   mtx_out.lock ();
 
@@ -1777,7 +1789,7 @@ semaphore::_timedwait (const struct timespec *abstime)
   waitlength -= tv.tv_sec * 1000 + tv.tv_usec / 1000;
   if (waitlength < 0)
     waitlength = 0;
-  switch (pthread::cancelable_wait (win32_obj_id, waitlength, true, true))
+  switch (cancelable_wait (win32_obj_id, waitlength, true, cw_sig_eintr))
     {
     case WAIT_OBJECT_0:
       currentvalue--;
@@ -1799,7 +1811,7 @@ semaphore::_timedwait (const struct timespec *abstime)
 int
 semaphore::_wait ()
 {
-  switch (pthread::cancelable_wait (win32_obj_id, INFINITE, true, true))
+  switch (cancelable_wait (win32_obj_id, INFINITE, true, cw_sig_eintr))
     {
     case WAIT_OBJECT_0:
       currentvalue--;
@@ -2253,31 +2265,24 @@ pthread::join (pthread_t *thread, void **return_val)
       (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
       (*thread)->mutex.unlock ();
 
-      bool loop = false;
-      do
-       switch (cancelable_wait ((*thread)->win32_obj_id, INFINITE, false, true))
-         {
-         case WAIT_OBJECT_0:
-           if (return_val)
-             *return_val = (*thread)->return_ptr;
-           delete (*thread);
-           break;
-         case WAIT_SIGNALED:
-           _my_tls.call_signal_handler ();
-           loop = true;
-           break;
-         case WAIT_CANCELED:
-           // set joined thread back to joinable since we got canceled
-           (*thread)->joiner = NULL;
-           (*thread)->attr.joinable = PTHREAD_CREATE_JOINABLE;
-           joiner->cancel_self ();
-           // never reached
-           break;
-         default:
-           // should never happen
-           return EINVAL;
-         }
-      while (loop);
+      switch (cancelable_wait ((*thread)->win32_obj_id, INFINITE, false, cw_sig_resume))
+       {
+       case WAIT_OBJECT_0:
+         if (return_val)
+           *return_val = (*thread)->return_ptr;
+         delete (*thread);
+         break;
+       case WAIT_CANCELED:
+         // set joined thread back to joinable since we got canceled
+         (*thread)->joiner = NULL;
+         (*thread)->attr.joinable = PTHREAD_CREATE_JOINABLE;
+         joiner->cancel_self ();
+         // never reached
+         break;
+       default:
+         // should never happen
+         return EINVAL;
+       }
     }
 
   return 0;
index 8bd8b25..6cce1fa 100644 (file)
@@ -24,6 +24,13 @@ details. */
 #include <security.h>
 #include <errno.h>
 
+enum cw_sig_wait
+{
+  cw_sig_nosig,
+  cw_sig_eintr,
+  cw_sig_resume
+};
+
 extern "C"
 {
 void SetResourceLock (int, int, const char *) __attribute__ ((regparm (3)));
@@ -31,6 +38,9 @@ void ReleaseResourceLock (int, int, const char *)
   __attribute__ ((regparm (3)));
 }
 
+DWORD cancelable_wait (HANDLE, DWORD, const bool = true, const enum cw_sig_wait = cw_sig_nosig)
+  __attribute__ ((regparm (3)));
+
 class fast_mutex
 {
 public:
@@ -59,13 +69,13 @@ public:
 
   void lock ()
   {
-    if (InterlockedIncrement ((long *)&lock_counter) != 1)
-      WaitForSingleObject (win32_obj_id, INFINITE);
+    if (InterlockedIncrement ((long *) &lock_counter) != 1)
+      cancelable_wait (win32_obj_id, INFINITE, false, cw_sig_resume);
   }
 
   void unlock ()
   {
-    if (InterlockedDecrement ((long *)&lock_counter))
+    if (InterlockedDecrement ((long *) &lock_counter))
       ::ReleaseSemaphore (win32_obj_id, 1, NULL);
   }
 
@@ -397,8 +407,6 @@ public:
   virtual void testcancel ();
   static void static_cancel_self ();
 
-  static DWORD cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel = true, const bool do_sig_wait = false);
-
   virtual int setcancelstate (int state, int *oldstate);
   virtual int setcanceltype (int type, int *oldtype);
 
index 70febf0..2a7a94d 100644 (file)
@@ -80,7 +80,7 @@ wait4 (int intpid, int *status, int options, struct rusage *r)
       if ((waitfor = w->ev) == NULL)
        goto nochildren;
 
-      res = pthread::cancelable_wait (waitfor, INFINITE);
+      res = cancelable_wait (waitfor, INFINITE);
 
       sigproc_printf ("%d = WaitForSingleObject (...)", res);