Merge pull request #234 from FeepingCreature/fix/use-appropriate-mask-function

Fix timing issue with multiple threads
This commit is contained in:
Wolfgang Hommel
2020-03-12 21:39:17 +01:00
committed by GitHub

View File

@@ -2636,8 +2636,9 @@ struct LockedState {
static void pthread_cleanup_mutex_lock(void *data)
{
struct LockedState *state = data;
sigset_t original_mask = state->original_mask; // inside the lock!
pthread_mutex_unlock(&state->mutex);
sigprocmask(SIG_SETMASK, &state->original_mask, NULL);
pthread_sigmask(SIG_SETMASK, &original_mask, NULL);
}
#endif
@@ -2666,15 +2667,18 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp)
/* Sanity check by Karl Chan since v0.8 */
if (tp == NULL) return -1;
// {ret = value; goto abort;} to call matching pthread_cleanup_pop and return value
int ret = INT_MAX;
#ifdef PTHREAD_SINGLETHREADED_TIME
static struct LockedState state = { 0 };
// block all signals while locked. prevents deadlocks if signal interrupts in in mid-operation.
sigset_t all_signals;
sigset_t all_signals, original_mask;
sigfillset(&all_signals);
sigprocmask(SIG_SETMASK, &all_signals, &state.original_mask);
pthread_sigmask(SIG_SETMASK, &all_signals, &original_mask);
pthread_mutex_lock(&state.mutex);
state.original_mask = original_mask; // inside the lock!
pthread_cleanup_push(pthread_cleanup_mutex_lock, &state);
#endif
@@ -2720,10 +2724,14 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp)
{
/* Check whether we actually should be faking the returned timestamp. */
/* fprintf(stderr, "(libfaketime limits -> runtime: %lu, callcounter: %lu\n", (*time_tptr - ftpl_starttime), callcounter); */
if ((ft_start_after_secs != -1) && (tmp_ts.tv_sec < ft_start_after_secs)) return 0;
if ((ft_stop_after_secs != -1) && (tmp_ts.tv_sec >= ft_stop_after_secs)) return 0;
if ((ft_start_after_ncalls != -1) && (callcounter < ft_start_after_ncalls)) return 0;
if ((ft_stop_after_ncalls != -1) && (callcounter >= ft_stop_after_ncalls)) return 0;
if (((ft_start_after_secs != -1) && (tmp_ts.tv_sec < ft_start_after_secs))
|| ((ft_stop_after_secs != -1) && (tmp_ts.tv_sec >= ft_stop_after_secs))
|| ((ft_start_after_ncalls != -1) && (callcounter < ft_start_after_ncalls))
|| ((ft_stop_after_ncalls != -1) && (callcounter >= ft_stop_after_ncalls)))
{
ret = 0;
goto abort;
}
/* fprintf(stderr, "(libfaketime limits -> runtime: %lu, callcounter: %lu continues\n", (*time_tptr - ftpl_starttime), callcounter); */
}
@@ -2828,7 +2836,8 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp)
{
if (load_time(tp))
{
return 0;
ret = 0;
goto abort;
}
}
@@ -2891,12 +2900,16 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp)
break;
default:
return -1;
ret = -1;
goto abort;
} // end of switch(ft_mode)
abort:
#ifdef PTHREAD_SINGLETHREADED_TIME
pthread_cleanup_pop(1);
#endif
// came here via goto abort?
if (ret != INT_MAX) return ret;
save_time(tp);
/* Cache this most recent real and faked time we encountered */