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