瀏覽代碼

SIGEV_THREAD timers: fix fatal signal if internal SIGTIMER becomes unblocked

commit 6ae2568bc2367b4d47e0ea1cb043fd56e697912f introduced a fatal
signal condition if the internal timer signal used for SIGEV_THREAD
timers is unblocked. this can happen whenever the application alters
the signal mask with SIG_SETMASK, since sigset_t objects never include
the bits used for implementation-internal signals.

this patch effectively reverts the breakage by adding back a no-op
signal handler.

overruns will not be accounted if the timer signal becomes unblocked,
but POSIX does not specify them except for SIGEV_SIGNAL timers anyway.
Rich Felker 3 月之前
父節點
當前提交
47fa6e4fcc
共有 1 個文件被更改,包括 8 次插入1 次删除
  1. 8 1
      src/time/timer_create.c

+ 8 - 1
src/time/timer_create.c

@@ -22,6 +22,10 @@ static void dummy_0()
 }
 weak_alias(dummy_0, __pthread_tsd_run_dtors);
 
+static void timer_handler(int sig, siginfo_t *si, void *ctx)
+{
+}
+
 static void cleanup_fromsig(void *p)
 {
 	pthread_t self = __pthread_self();
@@ -98,7 +102,10 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict
 		break;
 	case SIGEV_THREAD:
 		if (!init) {
-			struct sigaction sa = { .sa_handler = SIG_DFL };
+			struct sigaction sa = {
+				.sa_sigaction = timer_handler,
+				.sa_flags = SA_SIGINFO | SA_RESTART
+			};
 			__libc_sigaction(SIGTIMER, &sa, 0);
 			a_store(&init, 1);
 		}