mirror of https://git.musl-libc.org/git/musl
Browse Source
1. the thread result field was reused for storing a kernel timer id, but would be overwritten if the application code exited or cancelled the thread. 2. low pointer values were used as the indicator that the timer id is a kernel timer id rather than a thread id. this is not portable, as mmap may return low pointers on some conditions. instead, use the fact that pointers must be aligned and kernel timer ids must be non-negative to map pointers into the negative integer space. 3. signals were not blocked until after the timer thread started, so a race condition could allow a signal handler to run in the timer thread when it's not supposed to exist. this is mainly problematic if the calling thread was the only thread where the signal was unblocked and the signal handler assumes it runs in that thread.rs-1.0
6 changed files with 36 additions and 22 deletions
@ -1,8 +1,12 @@ |
|||
#include <time.h> |
|||
#include <limits.h> |
|||
#include "pthread_impl.h" |
|||
|
|||
int timer_getoverrun(timer_t t) |
|||
{ |
|||
if ((uintptr_t)t >= 0x100000) t = ((pthread_t)t)->result; |
|||
if ((intptr_t)t < 0) { |
|||
pthread_t td = (void *)((uintptr_t)t << 1); |
|||
t = (void *)(uintptr_t)(td->timer_id & INT_MAX); |
|||
} |
|||
return syscall(SYS_timer_getoverrun, (long)t); |
|||
} |
|||
|
|||
@ -1,8 +1,12 @@ |
|||
#include <time.h> |
|||
#include <limits.h> |
|||
#include "pthread_impl.h" |
|||
|
|||
int timer_gettime(timer_t t, struct itimerspec *val) |
|||
{ |
|||
if ((uintptr_t)t >= 0x100000) t = ((pthread_t)t)->result; |
|||
if ((intptr_t)t < 0) { |
|||
pthread_t td = (void *)((uintptr_t)t << 1); |
|||
t = (void *)(uintptr_t)(td->timer_id & INT_MAX); |
|||
} |
|||
return syscall(SYS_timer_gettime, (long)t, val); |
|||
} |
|||
|
|||
@ -1,8 +1,12 @@ |
|||
#include <time.h> |
|||
#include <limits.h> |
|||
#include "pthread_impl.h" |
|||
|
|||
int timer_settime(timer_t t, int flags, const struct itimerspec *restrict val, struct itimerspec *restrict old) |
|||
{ |
|||
if ((uintptr_t)t >= 0x100000) t = ((pthread_t)t)->result; |
|||
if ((intptr_t)t < 0) { |
|||
pthread_t td = (void *)((uintptr_t)t << 1); |
|||
t = (void *)(uintptr_t)(td->timer_id & INT_MAX); |
|||
} |
|||
return syscall(SYS_timer_settime, (long)t, flags, val, old); |
|||
} |
|||
|
|||
Loading…
Reference in new issue