aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2005-06-09 05:11:51 +0000
committerChristopher Faylor <me@cgf.cx>2005-06-09 05:11:51 +0000
commited364fa9fbf461ef2f1b17ba17f210dd1066f6b3 (patch)
treeb058e5fd170aa4685c383e35001c9251d5610dce
parenta63c42932ecf41c1141789282838407329524e2c (diff)
downloadnewlib-ed364fa9fbf461ef2f1b17ba17f210dd1066f6b3.zip
newlib-ed364fa9fbf461ef2f1b17ba17f210dd1066f6b3.tar.gz
newlib-ed364fa9fbf461ef2f1b17ba17f210dd1066f6b3.tar.bz2
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.
-rw-r--r--winsup/cygwin/ChangeLog9
-rw-r--r--winsup/cygwin/exceptions.cc2
-rw-r--r--winsup/cygwin/signal.cc2
-rw-r--r--winsup/cygwin/thread.cc85
-rw-r--r--winsup/cygwin/thread.h18
-rw-r--r--winsup/cygwin/wait.cc2
6 files changed, 70 insertions, 48 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index f7c908c..6b0a04d 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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.
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index b886e34..6e44b5b 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -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
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc
index 1808b24..935083c 100644
--- a/winsup/cygwin/signal.cc
+++ b/winsup/cygwin/signal.cc
@@ -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;
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index e2ffe8e..9a3c7af 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -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;
diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h
index 8bd8b25..6cce1fa 100644
--- a/winsup/cygwin/thread.h
+++ b/winsup/cygwin/thread.h
@@ -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);
diff --git a/winsup/cygwin/wait.cc b/winsup/cygwin/wait.cc
index 70febf0..2a7a94d 100644
--- a/winsup/cygwin/wait.cc
+++ b/winsup/cygwin/wait.cc
@@ -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);