mirror of
git://git.musl-libc.org/musl
synced 2025-03-06 20:48:29 +01:00
fix thread leak on timer_create(SIGEV_THREAD) failure
After commit5b74eed3b3
the timer thread doesn't check whether timer_create() actually created the timer, proceeding to wait for a signal that might never arrive. We can't fix this by simply checking for a negative timer_id after pthread_barrier_wait() because we have no way to distinguish a timer creation failure and a request to delete a timer with INT_MAX id if it happens to arrive quickly (a variation of this bug existed before5b74eed3b3
, where the timer would be leaked in this case). So (ab)use cancel field of pthread_t instead.
This commit is contained in:
parent
bf14ef193b
commit
3ad3fa962e
1 changed files with 5 additions and 1 deletions
|
@ -43,6 +43,8 @@ static void *start(void *arg)
|
|||
union sigval val = args->sev->sigev_value;
|
||||
|
||||
pthread_barrier_wait(&args->b);
|
||||
if (self->cancel)
|
||||
return 0;
|
||||
for (;;) {
|
||||
siginfo_t si;
|
||||
while (sigwaitinfo(SIGTIMER_SET, &si) < 0);
|
||||
|
@ -113,8 +115,10 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict
|
|||
ksev.sigev_signo = SIGTIMER;
|
||||
ksev.sigev_notify = SIGEV_THREAD_ID;
|
||||
ksev.sigev_tid = td->tid;
|
||||
if (syscall(SYS_timer_create, clk, &ksev, &timerid) < 0)
|
||||
if (syscall(SYS_timer_create, clk, &ksev, &timerid) < 0) {
|
||||
timerid = -1;
|
||||
td->cancel = 1;
|
||||
}
|
||||
td->timer_id = timerid;
|
||||
pthread_barrier_wait(&args.b);
|
||||
if (timerid < 0) return -1;
|
||||
|
|
Loading…
Add table
Reference in a new issue