diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din index 426cf172c..1e971cf92 100644 --- a/winsup/cygwin/common.din +++ b/winsup/cygwin/common.din @@ -1135,6 +1135,8 @@ pthread_spin_trylock SIGFE pthread_spin_unlock SIGFE pthread_suspend SIGFE pthread_testcancel SIGFE +pthread_timedjoin_np SIGFE +pthread_tryjoin_np SIGFE pthread_yield = sched_yield SIGFE ptsname SIGFE ptsname_r SIGFE diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 958acca3a..b461fa9c7 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -495,12 +495,13 @@ details. */ 324: Export sigtimedwait. 325: Export catclose, catgets, catopen. 326: Export clearenv + 327: Export pthread_tryjoin_np, pthread_timedjoin_np. Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 326 +#define CYGWIN_VERSION_API_MINOR 327 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible changes are made to the shared diff --git a/winsup/cygwin/include/pthread.h b/winsup/cygwin/include/pthread.h index fed616532..beaac59de 100644 --- a/winsup/cygwin/include/pthread.h +++ b/winsup/cygwin/include/pthread.h @@ -154,6 +154,8 @@ int pthread_getcpuclockid (pthread_t, clockid_t *); int pthread_getschedparam (pthread_t, int *, struct sched_param *); void *pthread_getspecific (pthread_key_t); int pthread_join (pthread_t, void **); +int pthread_tryjoin_np (pthread_t, void **); +int pthread_timedjoin_np (pthread_t, void **, const struct timespec *); int pthread_key_create (pthread_key_t *, void (*)(void *)); int pthread_key_delete (pthread_key_t); diff --git a/winsup/cygwin/pthread.cc b/winsup/cygwin/pthread.cc index b9da2eff7..e7f87f9fe 100644 --- a/winsup/cygwin/pthread.cc +++ b/winsup/cygwin/pthread.cc @@ -41,12 +41,6 @@ pthread_exit (void *value_ptr) __builtin_unreachable (); /* FIXME: don't know why this is necessary */ } -int -pthread_join (pthread_t thread, void **return_val) -{ - return pthread::join (&thread, (void **) return_val); -} - int pthread_detach (pthread_t thread) { diff --git a/winsup/cygwin/release/2.11.0 b/winsup/cygwin/release/2.11.0 index e807b6e9d..b1aaaf3bb 100644 --- a/winsup/cygwin/release/2.11.0 +++ b/winsup/cygwin/release/2.11.0 @@ -1,7 +1,8 @@ What's new: ----------- -- New API: clearenv. +- New API: clearenv, pthread_tryjoin_np, pthread_timedjoin_np. + What changed: ------------- diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 9f2e18357..2734d1754 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -2421,7 +2421,7 @@ pthread_attr_destroy (pthread_attr_t *attr) } int -pthread::join (pthread_t *thread, void **return_val) +pthread::join (pthread_t *thread, void **return_val, PLARGE_INTEGER timeout) { pthread_t joiner = self (); @@ -2453,7 +2453,7 @@ pthread::join (pthread_t *thread, void **return_val) (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED; (*thread)->mutex.unlock (); - switch (cygwait ((*thread)->win32_obj_id, cw_infinite, + switch (cygwait ((*thread)->win32_obj_id, timeout, cw_sig | cw_sig_restart | cw_cancel)) { case WAIT_OBJECT_0: @@ -2468,6 +2468,11 @@ pthread::join (pthread_t *thread, void **return_val) joiner->cancel_self (); // never reached break; + case WAIT_TIMEOUT: + // set joined thread back to joinable since we got canceled + (*thread)->joiner = NULL; + (*thread)->attr.joinable = PTHREAD_CREATE_JOINABLE; + return EBUSY; default: // should never happen return EINVAL; @@ -2574,6 +2579,32 @@ pthread_convert_abstime (clockid_t clock_id, const struct timespec *abstime, return 0; } +extern "C" int +pthread_join (pthread_t thread, void **return_val) +{ + return pthread::join (&thread, (void **) return_val, NULL); +} + +extern "C" int +pthread_tryjoin_np (pthread_t thread, void **return_val) +{ + LARGE_INTEGER timeout = { 0, 0 }; + + return pthread::join (&thread, (void **) return_val, &timeout); +} + +extern "C" int +pthread_timedjoin_np (pthread_t thread, void **return_val, + const struct timespec *abstime) +{ + LARGE_INTEGER timeout; + + int err = pthread_convert_abstime (CLOCK_REALTIME, abstime, &timeout); + if (err) + return err; + return pthread::join (&thread, (void **) return_val, &timeout); +} + extern "C" int pthread_getattr_np (pthread_t thread, pthread_attr_t *attr) { diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index 9f5e19bda..4c6557aef 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -375,7 +375,7 @@ public: /* API calls */ static int cancel (pthread_t); - static int join (pthread_t * thread, void **return_val); + static int join (pthread_t * thread, void **return_val, PLARGE_INTEGER); static int detach (pthread_t * thread); static int create (pthread_t * thread, const pthread_attr_t * attr, void *(*start_routine) (void *), void *arg);