Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog10
-rw-r--r--winsup/cygwin/thread.cc70
-rw-r--r--winsup/cygwin/thread.h4
3 files changed, 71 insertions, 13 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 8d6890288..a6a0d1daa 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,15 @@
2003-01-09 Thomas Pfaff <tpfaff@gmx.net>
+ * thread.h (WAIT_CANCELED): New define.
+ (pthread::cancelable_wait): New static method.
+ * thread.cc (pthread::cancelable_wait): Implement.
+ (semaphore::Wait): Wait on semaphore and thread cancellation.
+ (pthread::join): Wait on joined thread and thread cancellation.
+ (semaphore::wait): Add testcancel to check for thread
+ cancellation even if the semaphore is available.
+
+2003-01-09 Thomas Pfaff <tpfaff@gmx.net>
+
* include/pthread.h: Add define for errorchecking mutexes.
Change default mutex type.
* thread.cc (pthread_cond::TimedWait): Update mutex unlock
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index 2aac4b3b3..dee6eb05a 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -471,7 +471,7 @@ pwrite ()
read ()
readv ()
select ()
-sem_wait ()
+*sem_wait ()
sigpause ()
sigsuspend ()
sigtimedwait ()
@@ -632,6 +632,28 @@ pthread::static_cancel_self (void)
}
+DWORD pthread::cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel)
+{
+ DWORD res;
+ HANDLE wait_objects[2];
+ pthread_t thread = self ();
+
+ if (!isGoodObject (&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[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 ();
+ return res;
+}
+
int
pthread::setcancelstate (int state, int *oldstate)
{
@@ -1390,8 +1412,15 @@ semaphore::TryWait ()
void
semaphore::Wait ()
{
- WaitForSingleObject (win32_obj_id, INFINITE);
- currentvalue--;
+ switch (pthread::cancelable_wait (win32_obj_id, INFINITE))
+ {
+ case WAIT_OBJECT_0:
+ currentvalue--;
+ break;
+ default:
+ debug_printf ("cancelable_wait failed. %E");
+ return;
+ }
}
void
@@ -1850,14 +1879,15 @@ pthread::join (pthread_t *thread, void **return_val)
{
pthread_t joiner = self ();
- if (!isGoodObject (&joiner))
- return EINVAL;
+ joiner->testcancel ();
// Initialize return val with NULL
if (return_val)
*return_val = NULL;
- /* FIXME: wait on the thread cancellation event as well - we are a cancellation point*/
+ if (!isGoodObject (&joiner))
+ return EINVAL;
+
if (!isGoodObject (thread))
return ESRCH;
@@ -1876,14 +1906,26 @@ pthread::join (pthread_t *thread, void **return_val)
(*thread)->joiner = joiner;
(*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
(*thread)->mutex.UnLock ();
- WaitForSingleObject ((*thread)->win32_obj_id, INFINITE);
- if (return_val)
- *return_val = (*thread)->return_ptr;
- // cleanup
- delete (*thread);
- } /* End if */
- pthread_testcancel ();
+ switch (cancelable_wait ((*thread)->win32_obj_id, INFINITE, false))
+ {
+ 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;
}
@@ -2629,6 +2671,8 @@ semaphore::destroy (sem_t *sem)
int
semaphore::wait (sem_t *sem)
{
+ pthread_testcancel ();
+
if (!isGoodObject (sem))
{
set_errno (EINVAL);
diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h
index cf08a7630..fad85e557 100644
--- a/winsup/cygwin/thread.h
+++ b/winsup/cygwin/thread.h
@@ -332,6 +332,8 @@ private:
static nativeMutex mutexInitializationLock;
};
+#define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
+
class pthread:public verifyable_object
{
public:
@@ -379,6 +381,8 @@ public:
virtual void testcancel ();
static void static_cancel_self ();
+ static DWORD cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel = true);
+
virtual int setcancelstate (int state, int *oldstate);
virtual int setcanceltype (int type, int *oldtype);