diff -r 3a57eafd8401 Python/condvar.h --- a/Python/condvar.h Tue May 24 09:15:14 2016 +0300 +++ b/Python/condvar.h Fri Jun 03 11:36:50 2016 +0200 @@ -87,6 +87,8 @@ #define PyCOND_BROADCAST(cond) pthread_cond_broadcast(cond) #define PyCOND_WAIT(cond, mut) pthread_cond_wait((cond), (mut)) +#define MINIMUM_TIMEOUT 100 + /* return 0 for success, 1 on timeout, -1 on error */ Py_LOCAL_INLINE(int) PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, PY_LONG_LONG us) @@ -95,10 +97,31 @@ struct timespec ts; struct timeval deadline; - PyCOND_GETTIMEOFDAY(&deadline); - PyCOND_ADD_MICROSECONDS(deadline, us); - ts.tv_sec = deadline.tv_sec; - ts.tv_nsec = deadline.tv_usec * 1000; + while(1) { + long delta; + struct timeval ct; + + PyCOND_GETTIMEOFDAY(&deadline); + PyCOND_ADD_MICROSECONDS(deadline, us); + ts.tv_sec = deadline.tv_sec; + ts.tv_nsec = deadline.tv_usec * 1000; + + /* Retry with a greater timeout when deadline is already in the past + * for a very slow hardware. When the timeout is greater than + * MINIMUM_TIMEOUT, it is considered that this cannot happen, whatever + * the hardware being used. */ + if (us < MINIMUM_TIMEOUT) { + PyCOND_GETTIMEOFDAY(&ct); + if ((delta=(ct.tv_sec - deadline.tv_sec) * 1000000 + + (ct.tv_usec - deadline.tv_usec)) > 0) { + us += delta; + printf("%ld\n", delta); + continue; + } + } + printf("Ok\n"); + break; + } r = pthread_cond_timedwait((cond), (mut), &ts); if (r == ETIMEDOUT)