diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2011-04-28 18:44:24 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2011-04-28 18:44:24 +0400 |
commit | 206a6ee9c811164526d05ac52717a114ff1050c2 (patch) | |
tree | 3f3a0a6218fcf0e630c10aba8d604073e3fb25b7 /winsup/cygwin/posix_ipc.cc | |
parent | fdb1f028721e32061c064ff28600b2685300437a (diff) |
* posix_ipc.cc (ipc_cond_timedwait): Also wait for pthread's
cancel_event, if any. Call pthread_testcancel if cancel_event has been
signalled.
Diffstat (limited to 'winsup/cygwin/posix_ipc.cc')
-rw-r--r-- | winsup/cygwin/posix_ipc.cc | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/winsup/cygwin/posix_ipc.cc b/winsup/cygwin/posix_ipc.cc index 04b3e58bc..227282fcb 100644 --- a/winsup/cygwin/posix_ipc.cc +++ b/winsup/cygwin/posix_ipc.cc @@ -174,10 +174,15 @@ ipc_cond_init (HANDLE *pevt, const char *name, char sr) static int ipc_cond_timedwait (HANDLE evt, HANDLE mtx, const struct timespec *abstime) { - HANDLE w4[3] = { evt, signal_arrived, NULL }; + pthread_t thread; + HANDLE w4[4] = { evt, signal_arrived, NULL, NULL }; DWORD cnt = 2; + DWORD timer_idx = 0; int ret = 0; + thread = pthread::self (); + if (thread && thread->cancel_event) + w4[cnt++] = thread->cancel_event; if (abstime) { if (abstime->tv_sec < 0 @@ -192,18 +197,18 @@ ipc_cond_timedwait (HANDLE evt, HANDLE mtx, const struct timespec *abstime) NTSTATUS status; LARGE_INTEGER duetime; - status = NtCreateTimer (&w4[2], TIMER_ALL_ACCESS, NULL, + timer_idx = cnt++; + status = NtCreateTimer (&w4[timer_idx], TIMER_ALL_ACCESS, NULL, NotificationTimer); if (!NT_SUCCESS (status)) return geterrno_from_nt_status (status); timespec_to_filetime (abstime, (FILETIME *) &duetime); - status = NtSetTimer (w4[2], &duetime, NULL, NULL, FALSE, 0, NULL); + status = NtSetTimer (w4[timer_idx], &duetime, NULL, NULL, FALSE, 0, NULL); if (!NT_SUCCESS (status)) { - NtClose (w4[2]); + NtClose (w4[timer_idx]); return geterrno_from_nt_status (status); } - cnt = 3; } ResetEvent (evt); if ((ret = ipc_mutex_unlock (mtx)) != 0) @@ -220,6 +225,10 @@ restart1: ret = EINTR; break; case WAIT_OBJECT_0 + 2: + if (timer_idx != 2) + pthread_testcancel (); + /*FALLTHRU*/ + case WAIT_OBJECT_0 + 3: ret = ETIMEDOUT; break; default: @@ -244,6 +253,10 @@ restart1: ret = EINTR; break; case WAIT_OBJECT_0 + 2: + if (timer_idx != 2) + pthread_testcancel (); + /*FALLTHRU*/ + case WAIT_OBJECT_0 + 3: ret = ETIMEDOUT; break; default: @@ -251,11 +264,11 @@ restart1: break; } } - if (w4[2]) + if (timer_idx) { if (ret != ETIMEDOUT) - NtCancelTimer (w4[2], NULL); - NtClose (w4[2]); + NtCancelTimer (w4[timer_idx], NULL); + NtClose (w4[timer_idx]); } return ret; } |