Refactor ft_shm_init and ftpl_init to remove duplication

Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
This commit is contained in:
Remi Gacogne
2025-12-16 16:30:25 +01:00
parent 7ba95f4cb0
commit c0aa6189f7

View File

@@ -341,12 +341,8 @@ static bool check_missing_real(const char *name, bool missing)
#define CHECK_MISSING_REAL(name) \
check_missing_real(#name, (NULL == real_##name))
#if defined(PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
static pthread_mutex_t initialized_once_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
#else
static pthread_mutex_t initialized_once_mutex;
static pthread_once_t initialized_once_control = PTHREAD_ONCE_INIT;
#endif
/* prototypes */
static int fake_gettimeofday(struct timeval *tv);
@@ -720,40 +716,59 @@ static void ft_shm_destroy(void)
}
}
#if defined(PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
static pthread_mutex_t ft_shm_initialized_once_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
#else
static void ft_initialize_errorcheck_mutex (pthread_mutex_t* mutex)
{
pthread_mutexattr_t attr;
int ret = pthread_mutexattr_init(&attr);
if (ret != 0) {
fprintf(stderr, "libfaketime: failed to initialize mutex attribute: %d\n", ret);
exit(-1);
}
ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
if (ret != 0) {
fprintf(stderr, "libfaketime: failed to set errorcheck mutex attribute: %d\n", ret);
exit(-1);
}
ret = pthread_mutex_init(mutex, &attr);
if (ret != 0) {
fprintf(stderr, "libfaketime: failed to initialize errorcheck mutex: %d\n", ret);
exit(-1);
}
}
static void ft_init_once_generic (bool* init_done, pthread_once_t* once_control, pthread_mutex_t* mutex, void (*init_mutex_cb)(void), void (*initializer_cb)(void))
{
pthread_once(once_control, init_mutex_cb);
int ret = pthread_mutex_lock(mutex);
if (ret == 0) {
if (!*init_done) {
// Set this to `true` before we call the initialisation; the effect is that
// recursive calls to `ftpl_init` or `ft_shm_really_init` will be suppressed.
// If anything that they use calls back to a time function
// it will get some not- or partially-set-up faketime state.
// We are betting that that's good enough.
// (Empirically, on some platforms the shm functions call `statx`;
// we think the timestamps in that call probably don't matter.)
*init_done = true;
initializer_cb();
}
pthread_mutex_unlock(mutex);
}
}
static pthread_mutex_t ft_shm_initialized_once_mutex;
static pthread_once_t ft_shm_initialized_once_control = PTHREAD_ONCE_INIT;
static void ft_shm_init_mutex (void)
{
pthread_mutexattr_t attr;
if (pthread_mutexattr_init(&attr) != 0) {
return;
}
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0) {
return;
}
pthread_mutex_init(&ft_shm_initialized_once_mutex, &attr);
ft_initialize_errorcheck_mutex(&ft_shm_initialized_once_mutex);
}
#endif
static void ft_shm_really_init (void);
static void ft_shm_init (void)
{
static bool init_done = false;
#if !defined(PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
pthread_once(&ft_shm_initialized_once_control, ft_shm_init_mutex);
#endif
int ret = pthread_mutex_lock(&ft_shm_initialized_once_mutex);
if (ret == 0) {
if (!init_done) {
init_done = true;
ft_shm_really_init();
}
pthread_mutex_unlock(&ft_shm_initialized_once_mutex);
}
ft_init_once_generic(&init_done, &ft_shm_initialized_once_control, &ft_shm_initialized_once_mutex, &ft_shm_init_mutex, &ft_shm_really_init);
}
static void ft_shm_really_init (void)
@@ -3289,33 +3304,14 @@ static void ftpl_really_init(void)
dont_fake = dont_fake_final;
}
#if !defined(PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
static void init_initialized_once_mutex (void)
{
pthread_mutexattr_t attr;
if (pthread_mutexattr_init(&attr) != 0) {
return;
}
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0) {
return;
}
pthread_mutex_init(&initialized_once_mutex, &attr);
ft_initialize_errorcheck_mutex(&initialized_once_mutex);
}
#endif
inline static void ftpl_init(void) {
static bool init_done = false;
#if !defined(PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
pthread_once(&initialized_once_control, init_initialized_once_mutex);
#endif
int ret = pthread_mutex_lock(&initialized_once_mutex);
if (ret == 0) {
if (!init_done) {
init_done = true;
ftpl_really_init();
}
pthread_mutex_unlock(&initialized_once_mutex);
}
ft_init_once_generic(&init_done, &initialized_once_control, &initialized_once_mutex, &init_initialized_once_mutex, &ftpl_really_init);
}
void *ft_dlvsym(void *handle, const char *symbol, const char *version,