diff options
author | wm4 <wm4@nowhere> | 2014-02-26 20:44:27 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-02-26 21:03:35 +0100 |
commit | 9ccbc03ab17d3aa54cf91945ba1cdb77b60a2167 (patch) | |
tree | 266b94a00e6ca230b328e2a1a6d7ef8b569121c8 /osdep/threads.c | |
parent | 412bb336ab740ef42c36d1bd4a786f1382d2ccd3 (diff) | |
download | mpv-9ccbc03ab17d3aa54cf91945ba1cdb77b60a2167.tar.bz2 mpv-9ccbc03ab17d3aa54cf91945ba1cdb77b60a2167.tar.xz |
threads: fix wait time overflow check
When passing a very large timeout to mpthread_cond_timed_wait(), the
calculations could overflow, setting tv_sec to a negative value, and
making the pthread_cond_timed_wait() call return immediately. This
accidentally made Lua support poll and burn CPU for no reason.
The existing overflow check was ineffective on 32 bit systems. tv_sec is
usually a long, so adding INT_MAX to it will usually not overflow on 64
bit systems, but on 32 bit systems it's guaranteed to overflow. Simply
fix by clamping against a relatively high value. This will work until 1
week before the UNIX time wraps around in 32 bits.
Diffstat (limited to 'osdep/threads.c')
-rw-r--r-- | osdep/threads.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/osdep/threads.c b/osdep/threads.c index 0f72599641..2beb67df14 100644 --- a/osdep/threads.c +++ b/osdep/threads.c @@ -39,8 +39,8 @@ static void get_pthread_time(struct timespec *out_ts) static void timespec_add_seconds(struct timespec *ts, double seconds) { - if (seconds > INT_MAX) - seconds = INT_MAX; + // clamp to 1 week to avoid tv_sec overflows + seconds = MPMIN(seconds, 60 * 60 * 24 * 7); unsigned long secs = (int)seconds; unsigned long nsecs = (seconds - secs) * 1000000000UL; if (nsecs + ts->tv_nsec >= 1000000000UL) { |