]> git.sesse.net Git - vlc/blobdiff - src/misc/mtime.c
misc/events.c: Fix a leak in debug mode.
[vlc] / src / misc / mtime.c
index 8849b2a21e2c579a567cea4c94fe3d25f295fdbb..63d79a5b749ba25377363560320b0fba2e74ce2e 100644 (file)
 
 #include <vlc/vlc.h>
 
-#include <stdio.h>                                              /* sprintf() */
 #include <time.h>                      /* clock_gettime(), clock_nanosleep() */
-#include <stdlib.h>                                               /* lldiv() */
 #include <assert.h>
+#include <errno.h>
 
 
 #if defined( PTH_INIT_IN_PTH_H )                                  /* GNU Pth */
@@ -128,6 +127,11 @@ static inline unsigned mprec( void )
 
 static unsigned prec = 0;
 static volatile mtime_t cached_time = 0;
+#if defined( HAVE_CLOCK_NANOSLEEP ) 
+#  if (_POSIX_MONOTONIC_CLOCK - 0 < 0)
+#    define CLOCK_MONOTONIC CLOCK_REALTIME
+#  endif
+#endif
 
 /**
  * Return high precision date
@@ -142,10 +146,8 @@ mtime_t mdate( void )
 #if defined (HAVE_CLOCK_NANOSLEEP)
     struct timespec ts;
 
-# if (_POSIX_MONOTONIC_CLOCK - 0 >= 0)
     /* Try to use POSIX monotonic clock if available */
-    if( clock_gettime( CLOCK_MONOTONIC, &ts ) )
-# endif
+    if( clock_gettime( CLOCK_MONOTONIC, &ts ) == EINVAL )
         /* Run-time fallback to real-time clock (always available) */
         (void)clock_gettime( CLOCK_REALTIME, &ts );
 
@@ -223,9 +225,9 @@ mtime_t mdate( void )
         {
             /* Counter wrapped */
             i_wrap_counts++;
-            usec_time += I64C(0x100000000) * 1000;
+            res += I64C(0x100000000) * 1000;
         }
-        i_previous_time = usec_time;
+        i_previous_time = res;
         LeaveCriticalSection( &date_lock );
     }
 #else
@@ -261,10 +263,14 @@ void mwait( mtime_t date )
     lldiv_t d = lldiv( date, 1000000 );
     struct timespec ts = { d.quot, d.rem * 1000 };
 
-# if (_POSIX_MONOTONIC_CLOCK - 0 >= 0)
-    if( clock_nanosleep( CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL ) )
-# endif
-        clock_nanosleep( CLOCK_REALTIME, TIMER_ABSTIME, &ts, NULL );
+    int val;
+    while( ( val = clock_nanosleep( CLOCK_MONOTONIC, TIMER_ABSTIME, &ts,
+                                    NULL ) ) == EINTR );
+    if( val == EINVAL )
+    {
+        ts.tv_sec = d.quot; ts.tv_nsec = d.rem * 1000;
+        while( clock_nanosleep( CLOCK_REALTIME, 0, &ts, NULL ) == EINTR );
+    }
 #else
 
     mtime_t delay = date - mdate();
@@ -288,10 +294,13 @@ void msleep( mtime_t delay )
     lldiv_t d = lldiv( delay, 1000000 );
     struct timespec ts = { d.quot, d.rem * 1000 };
 
-# if (_POSIX_MONOTONIC_CLOCK - 0 >= 0)
-    if( clock_nanosleep( CLOCK_MONOTONIC, 0, &ts, NULL ) )
-# endif
-        clock_nanosleep( CLOCK_REALTIME, 0, &ts, NULL );
+    int val;
+    while( ( val = clock_nanosleep( CLOCK_MONOTONIC, 0, &ts, &ts ) ) == EINTR );
+    if( val == EINVAL )
+    {
+        ts.tv_sec = d.quot; ts.tv_nsec = d.rem * 1000;
+        while( clock_nanosleep( CLOCK_REALTIME, 0, &ts, &ts ) == EINTR );
+    }
 
 #elif defined( HAVE_KERNEL_OS_H )
     snooze( delay );
@@ -311,7 +320,7 @@ void msleep( mtime_t delay )
     ts_delay.tv_sec = delay / 1000000;
     ts_delay.tv_nsec = (delay % 1000000) * 1000;
 
-    nanosleep( &ts_delay, NULL );
+    while( nanosleep( &ts_delay, &ts_delay ) && ( errno == EINTR ) );
 
 #else
     struct timeval tv_delay;
@@ -319,10 +328,8 @@ void msleep( mtime_t delay )
     tv_delay.tv_sec = delay / 1000000;
     tv_delay.tv_usec = delay % 1000000;
 
-    /* select() return value should be tested, since several possible errors
-     * can occur. However, they should only happen in very particular occasions
-     * (i.e. when a signal is sent to the thread, or when memory is full), and
-     * can be ignored. */
+    /* If a signal is caught, you are screwed. Update your OS to nanosleep()
+     * or clock_nanosleep() if this is an issue. */
     select( 0, NULL, NULL, NULL, &tv_delay );
 #endif
 
@@ -423,7 +430,10 @@ mtime_t date_Increment( date_t *p_date, uint32_t i_nb_samples )
     return p_date->date;
 }
 
+#ifndef HAVE_GETTIMEOFDAY
+
 #ifdef WIN32
+
 /*
  * Number of micro-seconds between the beginning of the Windows epoch
  * (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970).
@@ -460,9 +470,10 @@ static int gettimeofday (struct timeval *tv, void *tz )
     tv->tv_usec = (long) (tim % 1000000L);
     return (0);
 }
-#endif
 
+#endif
 
+#endif
 
 /**
  * @return NTP 64-bits timestamp in host byte order.