* posix_ipc.cc (ipc_cond_timedwait): Also wait for pthread's

cancel_event, if any.  Call pthread_testcancel if cancel_event has been
	signalled.
This commit is contained in:
Corinna Vinschen 2011-04-28 14:44:24 +00:00
parent fdb1f02872
commit 206a6ee9c8
2 changed files with 27 additions and 8 deletions

View File

@ -1,3 +1,9 @@
2011-04-28 Corinna Vinschen <corinna@vinschen.de>
* 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 <corinna@vinschen.de> 2011-04-28 Corinna Vinschen <corinna@vinschen.de>
* posix_ipc.cc (ipc_cond_timedwait): Remove pthread_testcancel calls. * posix_ipc.cc (ipc_cond_timedwait): Remove pthread_testcancel calls.

View File

@ -174,10 +174,15 @@ ipc_cond_init (HANDLE *pevt, const char *name, char sr)
static int static int
ipc_cond_timedwait (HANDLE evt, HANDLE mtx, const struct timespec *abstime) 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 cnt = 2;
DWORD timer_idx = 0;
int ret = 0; int ret = 0;
thread = pthread::self ();
if (thread && thread->cancel_event)
w4[cnt++] = thread->cancel_event;
if (abstime) if (abstime)
{ {
if (abstime->tv_sec < 0 if (abstime->tv_sec < 0
@ -192,18 +197,18 @@ ipc_cond_timedwait (HANDLE evt, HANDLE mtx, const struct timespec *abstime)
NTSTATUS status; NTSTATUS status;
LARGE_INTEGER duetime; LARGE_INTEGER duetime;
status = NtCreateTimer (&w4[2], TIMER_ALL_ACCESS, NULL, timer_idx = cnt++;
status = NtCreateTimer (&w4[timer_idx], TIMER_ALL_ACCESS, NULL,
NotificationTimer); NotificationTimer);
if (!NT_SUCCESS (status)) if (!NT_SUCCESS (status))
return geterrno_from_nt_status (status); return geterrno_from_nt_status (status);
timespec_to_filetime (abstime, (FILETIME *) &duetime); 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)) if (!NT_SUCCESS (status))
{ {
NtClose (w4[2]); NtClose (w4[timer_idx]);
return geterrno_from_nt_status (status); return geterrno_from_nt_status (status);
} }
cnt = 3;
} }
ResetEvent (evt); ResetEvent (evt);
if ((ret = ipc_mutex_unlock (mtx)) != 0) if ((ret = ipc_mutex_unlock (mtx)) != 0)
@ -220,6 +225,10 @@ restart1:
ret = EINTR; ret = EINTR;
break; break;
case WAIT_OBJECT_0 + 2: case WAIT_OBJECT_0 + 2:
if (timer_idx != 2)
pthread_testcancel ();
/*FALLTHRU*/
case WAIT_OBJECT_0 + 3:
ret = ETIMEDOUT; ret = ETIMEDOUT;
break; break;
default: default:
@ -244,6 +253,10 @@ restart1:
ret = EINTR; ret = EINTR;
break; break;
case WAIT_OBJECT_0 + 2: case WAIT_OBJECT_0 + 2:
if (timer_idx != 2)
pthread_testcancel ();
/*FALLTHRU*/
case WAIT_OBJECT_0 + 3:
ret = ETIMEDOUT; ret = ETIMEDOUT;
break; break;
default: default:
@ -251,11 +264,11 @@ restart1:
break; break;
} }
} }
if (w4[2]) if (timer_idx)
{ {
if (ret != ETIMEDOUT) if (ret != ETIMEDOUT)
NtCancelTimer (w4[2], NULL); NtCancelTimer (w4[timer_idx], NULL);
NtClose (w4[2]); NtClose (w4[timer_idx]);
} }
return ret; return ret;
} }