mirror of
https://github.com/wolfcw/libfaketime.git
synced 2026-05-17 08:36:28 +03:00
Merge pull request #234 from FeepingCreature/fix/use-appropriate-mask-function
Fix timing issue with multiple threads
This commit is contained in:
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user