]> git.sesse.net Git - vlc/blobdiff - src/misc/mtime.c
Qt: actions_manager: Change constructor and inline some functions.
[vlc] / src / misc / mtime.c
index 5ab08c5e89a7487e227e50337369f49b153c51ca..2b27fbf40a05ecd74c17c0c90bb38a744dcbf3bf 100644 (file)
 #   include <mmsystem.h>
 #endif
 
-#if defined( UNDER_CE )
-#   include <windows.h>
-#endif
-
 #if defined(HAVE_SYS_TIME_H)
 #   include <sys/time.h>
 #endif
@@ -265,7 +261,7 @@ mtime_t mdate( void )
     }
     else
     {
-        /* Fallback on timeGetTime() which has a milisecond resolution
+        /* Fallback on timeGetTime() which has a millisecond resolution
          * (actually, best case is about 5 ms resolution)
          * timeGetTime() only returns a DWORD thus will wrap after
          * about 49.7 days so we try to detect the wrapping. */
@@ -314,6 +310,7 @@ mtime_t mdate( void )
     return res;
 }
 
+#undef mwait
 /**
  * Wait for a date
  *
@@ -340,8 +337,39 @@ void mwait( mtime_t date )
         ts.tv_sec = d.quot; ts.tv_nsec = d.rem * 1000;
         while( clock_nanosleep( CLOCK_REALTIME, 0, &ts, NULL ) == EINTR );
     }
-#else
 
+#elif defined (WIN32)
+    mtime_t i_total;
+
+    while( (i_total = (date - mdate())) > 0 )
+    {
+        const mtime_t i_sleep = i_total / 1000;
+        DWORD i_delay = (i_sleep > 0x7fffffff) ? 0x7fffffff : i_sleep;
+        vlc_testcancel();
+        SleepEx( i_delay, TRUE );
+    }
+    vlc_testcancel();
+
+#elif defined( __APPLE__ )
+    /* Explicit hack: OSX does not cancel at nanosleep() */
+    vlc_mutex_t lock;
+    vlc_cond_t  wait;
+
+    vlc_mutex_init (&lock);
+    vlc_cond_init (&wait);
+    vlc_mutex_lock (&lock);
+
+    vlc_cleanup_push (vlc_mutex_destroy, &lock);
+    vlc_cleanup_push (vlc_cond_destroy, &wait);
+    vlc_cleanup_push (vlc_mutex_unlock, &lock);
+
+    vlc_cond_timedwait (&wait, &lock, date);
+
+    vlc_cleanup_run ();
+    vlc_cleanup_run ();
+    vlc_cleanup_run ();
+
+#else
     mtime_t delay = date - mdate();
     if( delay > 0 )
         msleep( delay );
@@ -349,10 +377,27 @@ void mwait( mtime_t date )
 #endif
 }
 
+
+#include "libvlc.h" /* vlc_backtrace() */
+#undef msleep
+
+#if defined(__APPLE__) && defined( HAVE_NANOSLEEP )
+/* Mac OS X 10.5's nanosleep is not a cancellation point */
+static inline int
+semi_testcancelable_nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
+{
+    int ret;
+    pthread_testcancel();
+    ret = nanosleep(rqtp, rmtp);
+    pthread_testcancel();
+    return ret;
+}
+#define nanosleep semi_testcancelable_nanosleep
+#endif
+
 /**
- * More precise sleep()
+ * Portable usleep(). Cancellation point.
  *
- * Portable usleep() function.
  * \param delay the amount of time to sleep
  */
 void msleep( mtime_t delay )
@@ -372,10 +417,8 @@ void msleep( mtime_t delay )
 #elif defined( HAVE_KERNEL_OS_H )
     snooze( delay );
 
-#elif defined( WIN32 ) || defined( UNDER_CE )
-    for (delay /= 1000; delay > 0x7fffffff; delay -= 0x7fffffff)
-        Sleep (0x7fffffff);
-    Sleep (delay);
+#elif defined( WIN32 ) || defined( UNDER_CE ) || defined( __APPLE__ )
+    mwait (mdate () + delay);
 
 #elif defined( HAVE_NANOSLEEP )
     struct timespec ts_delay;
@@ -427,6 +470,8 @@ void date_Init( date_t *p_date, uint32_t i_divider_n, uint32_t i_divider_d )
 
 void date_Change( date_t *p_date, uint32_t i_divider_n, uint32_t i_divider_d )
 {
+    /* change time scale of remainder */
+    p_date->i_remainder = p_date->i_remainder * i_divider_n / p_date->i_divider_num;
     p_date->i_divider_num = i_divider_n;
     p_date->i_divider_den = i_divider_d;
 }
@@ -475,14 +520,15 @@ void date_Move( date_t *p_date, mtime_t i_difference )
  */
 mtime_t date_Increment( date_t *p_date, uint32_t i_nb_samples )
 {
-    mtime_t i_dividend = (mtime_t)i_nb_samples * 1000000;
-    p_date->date += i_dividend / p_date->i_divider_num * p_date->i_divider_den;
+    mtime_t i_dividend = (mtime_t)i_nb_samples * 1000000 * p_date->i_divider_den;
+    p_date->date += i_dividend / p_date->i_divider_num;
     p_date->i_remainder += (int)(i_dividend % p_date->i_divider_num);
 
     if( p_date->i_remainder >= p_date->i_divider_num )
     {
         /* This is Bresenham algorithm. */
-        p_date->date += p_date->i_divider_den;
+        assert( p_date->i_remainder < 2*p_date->i_divider_num);
+        p_date->date += 1;
         p_date->i_remainder -= p_date->i_divider_num;
     }