diff options
| -rw-r--r-- | src/time/timer_create.c | 35 | ||||
| -rw-r--r-- | src/time/timer_delete.c | 2 | 
2 files changed, 16 insertions, 21 deletions
diff --git a/src/time/timer_create.c b/src/time/timer_create.c index d9fbaee5..94219574 100644 --- a/src/time/timer_create.c +++ b/src/time/timer_create.c @@ -34,16 +34,6 @@ static void cleanup_fromsig(void *p)  static void timer_handler(int sig, siginfo_t *si, void *ctx)  { -	pthread_t self = __pthread_self(); -	jmp_buf jb; -	void (*notify)(union sigval) = (void (*)(union sigval))self->start; -	union sigval val = { .sival_ptr = self->start_arg }; - -	if (!setjmp(jb) && si->si_code == SI_TIMER) { -		pthread_cleanup_push(cleanup_fromsig, jb); -		notify(val); -		pthread_cleanup_pop(1); -	}  }  static void install_handler() @@ -59,20 +49,24 @@ static void *start(void *arg)  {  	pthread_t self = __pthread_self();  	struct start_args *args = arg; -	int id; +	int id = self->timer_id; +	jmp_buf jb; -	/* Reuse no-longer-needed thread structure fields to avoid -	 * needing the timer address in the signal handler. */ -	self->start = (void *(*)(void *))args->sev->sigev_notify_function; -	self->start_arg = args->sev->sigev_value.sival_ptr; +	void (*notify)(union sigval) = args->sev->sigev_notify_function; +	union sigval val = args->sev->sigev_value;  	pthread_barrier_wait(&args->b); -	if ((id = self->timer_id) >= 0) { -		__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, -			SIGTIMER_SET, 0, _NSIG/8); -		__wait(&self->timer_id, 0, id, 1); -		__syscall(SYS_timer_delete, id); +	for (;;) { +		siginfo_t si; +		while (sigwaitinfo(SIGTIMER_SET, &si) < 0); +		if (si.si_code == SI_TIMER && !setjmp(jb)) { +			pthread_cleanup_push(cleanup_fromsig, jb); +			notify(val); +			pthread_cleanup_pop(1); +		} +		if (self->timer_id < 0) break;  	} +	__syscall(SYS_timer_delete, id);  	return 0;  } @@ -112,6 +106,7 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict  		args.sev = evp;  		__block_app_sigs(&set); +		__syscall(SYS_rt_sigprocmask, SIG_BLOCK, SIGTIMER_SET, 0, _NSIG/8);  		r = pthread_create(&td, &attr, start, &args);  		__restore_sigs(&set);  		if (r) { diff --git a/src/time/timer_delete.c b/src/time/timer_delete.c index 7c97eeb1..b0bfac09 100644 --- a/src/time/timer_delete.c +++ b/src/time/timer_delete.c @@ -7,7 +7,7 @@ int timer_delete(timer_t t)  	if ((intptr_t)t < 0) {  		pthread_t td = (void *)((uintptr_t)t << 1);  		a_store(&td->timer_id, td->timer_id | INT_MIN); -		__wake(&td->timer_id, 1, 1); +		__syscall(SYS_tkill, td->tid, SIGTIMER);  		return 0;  	}  	return __syscall(SYS_timer_delete, t);  | 
