summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMathis Beer <Mathis.Beer@funkwerk-itk.com>2020-03-11 14:34:25 +0100
committerMathis Beer <Mathis.Beer@funkwerk-itk.com>2020-03-12 06:45:43 +0100
commitb4dea2ef9b529e2a7fb8619d68f0830ff957d3de (patch)
tree814859a9a4d6aa28b7f0eef6ce7e4fd5e3930c7a /src
parent796b30bebf5a74ac73ad506da8576e3445090131 (diff)
downloadlibfaketime-b4dea2ef9b529e2a7fb8619d68f0830ff957d3de.tar.gz
Unlock faketime lock on all return paths from libfaketime.c.
These gymnastics are necessary because pthread_cleanup_push and pthread_cleanup_pop must match exactly 1:1 and appear at the same level of indentation. This is because pthread_cleanup_push/pop are implemented in such a way that pthread_cleanup_push opens a scope and pthread_cleanup_pop closes it. They're macros with unbalanced brackets. C, ladies and gentlemen. So instead of returning, we have to set a field indicating our intent to return and then jump to the unlock site.
Diffstat (limited to 'src')
-rw-r--r--src/libfaketime.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/libfaketime.c b/src/libfaketime.c
index d9f1fc0..17ebaa2 100644
--- a/src/libfaketime.c
+++ b/src/libfaketime.c
@@ -2666,6 +2666,9 @@ 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 };
@@ -2719,10 +2722,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); */
}
@@ -2827,7 +2834,8 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp)
{
if (load_time(tp))
{
- return 0;
+ ret = 0;
+ goto abort;
}
}
@@ -2890,12 +2898,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 */