eina: Fix _timedwait to handle the given timeout on top of the absolute time
authorStefan Schmidt <s.schmidt@samsung.com>
Wed, 22 Oct 2014 13:36:57 +0000 (15:36 +0200)
committerStefan Schmidt <s.schmidt@samsung.com>
Thu, 23 Oct 2014 09:01:35 +0000 (11:01 +0200)
The pthread man page clearly states that pthread_cond_timedwait() takes an
absolute time parameter. So far we always passed it epoch plus timeout in
seconds. This would never trigger the timeout.

Making sure we fill out timespec struct with the current time before adding
the timeout as offset now. Also handling the t < 0 error case.

Various version worked up together with Jean-Philippe Andre <jp.andre@samsung.com>

Fixes T1701

src/lib/eina/eina_inline_lock_posix.x

index 172e5714ec6a30402361c8849df7a62ca3470bb5..7897946b4b55eb788bc4d3136b9f1582ba4636a5 100644 (file)
@@ -58,6 +58,8 @@ typedef void (*Eina_Lock_Bt_Func) ();
 #include "eina_inlist.h"
 #endif
 
+#include "eina_inline_private.h"
+
 typedef struct _Eina_Lock Eina_Lock;
 typedef struct _Eina_RWLock Eina_RWLock;
 typedef struct _Eina_Condition Eina_Condition;
@@ -376,6 +378,14 @@ eina_condition_timedwait(Eina_Condition *cond, double t)
 {
    struct timespec tv;
    Eina_Bool r;
+   time_t sec;
+   long nsec;
+
+   if (t < 0)
+     {
+        errno = EINVAL;
+        return EINA_FALSE;
+     }
 
 #ifdef EINA_HAVE_DEBUG_THREADS
    assert(_eina_threads_activated);
@@ -387,8 +397,16 @@ eina_condition_timedwait(Eina_Condition *cond, double t)
    pthread_mutex_unlock(&_eina_tracking_lock);
 #endif
 
-   tv.tv_sec = t;
-   tv.tv_nsec = (t - (double) tv.tv_sec) * 1000000000;
+   _eina_time_get(&tv);
+   sec = (time_t)t;
+   nsec = (t - (double) sec) * 1000000000L;
+   tv.tv_sec += sec;
+   tv.tv_nsec += nsec;
+   if (tv.tv_nsec > 1000000000L)
+     {
+        tv.tv_sec++;
+        tv.tv_nsec -= 1000000000L;
+     }
 
    r = pthread_cond_timedwait(&(cond->condition),
                              &(cond->lock->mutex),