From 206a6ee9c811164526d05ac52717a114ff1050c2 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 28 Apr 2011 14:44:24 +0000 Subject: [PATCH] * posix_ipc.cc (ipc_cond_timedwait): Also wait for pthread's cancel_event, if any. Call pthread_testcancel if cancel_event has been signalled. --- winsup/cygwin/ChangeLog | 6 ++++++ winsup/cygwin/posix_ipc.cc | 29 +++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index d0c2edc8b..416ffaa72 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,9 @@ +2011-04-28 Corinna Vinschen + + * posix_ipc.cc (ipc_cond_timedwait): Also wait for pthread's + cancel_event, if any. Call pthread_testcancel if cancel_event has been + signalled. + 2011-04-28 Corinna Vinschen * posix_ipc.cc (ipc_cond_timedwait): Remove pthread_testcancel calls. 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; }