فهرست منبع

revert to deleting kernel-level timer from cancellation handler

this is necessary in order to avoid breaking timer_getoverrun in the
last run of the timer event handler, if it has not yet finished.
Rich Felker 14 سال پیش
والد
کامیت
6f1414e102
2فایلهای تغییر یافته به همراه11 افزوده شده و 7 حذف شده
  1. 8 0
      src/time/timer_create.c
  2. 3 7
      src/time/timer_delete.c

+ 8 - 0
src/time/timer_create.c

@@ -24,6 +24,12 @@ void __sigtimer_handler(pthread_t self)
 	pthread_setcancelstate(st, 0);
 }
 
+static void cleanup(void *p)
+{
+	pthread_t self = p;
+	__syscall(SYS_timer_delete, self->result);
+}
+
 static void *start(void *arg)
 {
 	pthread_t self = __pthread_self();
@@ -35,10 +41,12 @@ static void *start(void *arg)
 	self->start_arg = args->sev->sigev_value.sival_ptr;
 	self->result = (void *)-1;
 
+	pthread_cleanup_push(cleanup, self);
 	pthread_barrier_wait(&args->b);
 	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
 	/* Loop on async-signal-safe cancellation point */
 	for (;;) sleep(1);
+	pthread_cleanup_pop(0);
 	return 0;
 }
 

+ 3 - 7
src/time/timer_delete.c

@@ -3,11 +3,7 @@
 
 int timer_delete(timer_t t)
 {
-	pthread_t td = 0;
-	int r;
-	if ((uintptr_t)t & 1) t = (void *)((unsigned long)t / 2);
-	else td = t, t = td->result;
-	r = __syscall(SYS_timer_delete, (long)t);
-	if (td) pthread_cancel(td);
-	return r;
+	if ((uintptr_t)t & 1)
+		return __syscall(SYS_timer_delete, ((unsigned long)t / 2));
+	return pthread_cancel(t);
 }