summaryrefslogtreecommitdiffstats
path: root/osdep
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-02-26 20:44:27 +0100
committerwm4 <wm4@nowhere>2014-02-26 21:03:35 +0100
commit9ccbc03ab17d3aa54cf91945ba1cdb77b60a2167 (patch)
tree266b94a00e6ca230b328e2a1a6d7ef8b569121c8 /osdep
parent412bb336ab740ef42c36d1bd4a786f1382d2ccd3 (diff)
downloadmpv-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')
-rw-r--r--osdep/threads.c4
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) {