* thread.cc (pthread::cancelable_wait): Rearrange slightly.

Add do_sig_wait parameter.  Wait for signal_arrived if set to true.
	Return WAIT_SIGNALED if signal arrived.
	(pthread_cond::wait): Accomodate change to pthread::cancelable_wait.
	(pthread::join): Ditto.
	(semaphore::_timedwait): Ditto.
	(semaphore::_wait): Ditto.  Change to return int to allow status
	feedback.
	(semaphore::wait): Return return value from semaphore::_wait.
	* thread.h (WAIT_SIGNALED): New definition.
	(pthread::cancelable_wait): Change declaration.  Define do_sig_wait
	as false by default to not interfere with existing calls accidentally.
	(semaphore::_wait): Declare int.
This commit is contained in:
Corinna Vinschen 2004-02-24 11:33:15 +00:00
parent ffde6695da
commit c9a76075f5
3 changed files with 65 additions and 25 deletions

View File

@ -1,3 +1,19 @@
2004-02-24 Corinna Vinschen <corinna@vinschen.de>
* thread.cc (pthread::cancelable_wait): Rearrange slightly.
Add do_sig_wait parameter. Wait for signal_arrived if set to true.
Return WAIT_SIGNALED if signal arrived.
(pthread_cond::wait): Accomodate change to pthread::cancelable_wait.
(pthread::join): Ditto.
(semaphore::_timedwait): Ditto.
(semaphore::_wait): Ditto. Change to return int to allow status
feedback.
(semaphore::wait): Return return value from semaphore::_wait.
* thread.h (WAIT_SIGNALED): New definition.
(pthread::cancelable_wait): Change declaration. Define do_sig_wait
as false by default to not interfere with existing calls accidentally.
(semaphore::_wait): Declare int.
2004-02-21 Christopher Faylor <cgf@redhat.com>
* exceptions.cc (sigpacket::process): Make sure that tls is filled in

View File

@ -537,27 +537,37 @@ pthread::static_cancel_self (void)
pthread::self ()->cancel_self ();
}
DWORD
pthread::cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel)
pthread::cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel,
const bool do_sig_wait)
{
DWORD res;
HANDLE wait_objects[2];
DWORD num = 0;
HANDLE wait_objects[3];
pthread_t thread = self ();
if (!is_good_object (&thread) || thread->cancelstate == PTHREAD_CANCEL_DISABLE)
return WaitForSingleObject (object, timeout);
/* Do not change the wait order.
The object must have higher priority than the cancel event,
because WaitForMultipleObjects will return the smallest index
if both objects are signaled. */
wait_objects[num++] = object;
if (is_good_object (&thread) &&
thread->cancelstate != PTHREAD_CANCEL_DISABLE)
wait_objects[num++] = thread->cancel_event;
if (do_sig_wait)
wait_objects[num++] = signal_arrived;
// Do not change the wait order
// The object must have higher priority than the cancel event,
// because WaitForMultipleObjects will return the smallest index
// if both objects are signaled
wait_objects[0] = object;
wait_objects[1] = thread->cancel_event;
res = WaitForMultipleObjects (2, wait_objects, FALSE, timeout);
if (do_cancel && res == WAIT_CANCELED)
pthread::static_cancel_self ();
res = WaitForMultipleObjects (num, wait_objects, FALSE, timeout);
if (res == WAIT_CANCELED)
{
if (num == 3 || !do_sig_wait)
{
if (do_cancel)
pthread::static_cancel_self ();
}
else
res = WAIT_SIGNALED;
}
return res;
}
@ -856,7 +866,7 @@ pthread_cond::wait (pthread_mutex_t mutex, DWORD dwMilliseconds)
++mutex->condwaits;
mutex->unlock ();
rv = pthread::cancelable_wait (sem_wait, dwMilliseconds, false);
rv = pthread::cancelable_wait (sem_wait, dwMilliseconds, false, true);
mtx_out.lock ();
@ -891,6 +901,13 @@ pthread_cond::wait (pthread_mutex_t mutex, DWORD dwMilliseconds)
if (rv == WAIT_CANCELED)
pthread::static_cancel_self ();
else if (rv == WAIT_SIGNALED)
/* SUSv3 states: If a signal is delivered to a thread waiting for a
condition variable, upon return from the signal handler the thread
resumes waiting for the condition variable as if it was not
interrupted, or it shall return zero due to spurious wakeup.
We opt for the latter choice here. */
return 0;
else if (rv == WAIT_TIMEOUT)
return ETIMEDOUT;
@ -1692,11 +1709,14 @@ 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))
switch (pthread::cancelable_wait (win32_obj_id, waitlength, true, true))
{
case WAIT_OBJECT_0:
currentvalue--;
break;
case WAIT_SIGNALED:
set_errno (EINTR);
return -1;
case WAIT_TIMEOUT:
set_errno (ETIMEDOUT);
return -1;
@ -1708,18 +1728,22 @@ semaphore::_timedwait (const struct timespec *abstime)
return 0;
}
void
int
semaphore::_wait ()
{
switch (pthread::cancelable_wait (win32_obj_id, INFINITE))
switch (pthread::cancelable_wait (win32_obj_id, INFINITE, true, true))
{
case WAIT_OBJECT_0:
currentvalue--;
break;
case WAIT_SIGNALED:
set_errno (EINTR);
return -1;
default:
debug_printf ("cancelable_wait failed. %E");
return;
break;
}
return 0;
}
void
@ -2157,7 +2181,7 @@ pthread::join (pthread_t *thread, void **return_val)
(*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
(*thread)->mutex.unlock ();
switch (cancelable_wait ((*thread)->win32_obj_id, INFINITE, false))
switch (cancelable_wait ((*thread)->win32_obj_id, INFINITE, false, false))
{
case WAIT_OBJECT_0:
if (return_val)
@ -3101,8 +3125,7 @@ semaphore::wait (sem_t *sem)
return -1;
}
(*sem)->_wait ();
return 0;
return (*sem)->_wait ();
}
int

View File

@ -347,6 +347,7 @@ private:
};
#define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
#define WAIT_SIGNALED (WAIT_OBJECT_0 + 2)
class _cygtls;
class pthread: public verifyable_object
@ -393,7 +394,7 @@ public:
virtual void testcancel ();
static void static_cancel_self ();
static DWORD cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel = true);
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);
@ -646,7 +647,7 @@ public:
}
private:
void _wait ();
int _wait ();
void _post ();
int _getvalue (int *sval);
int _trywait ();