]> git.sesse.net Git - vlc/commitdiff
* src/misc/mtime.c: fixed an overflow in mdate() on win32.
authorGildas Bazin <gbazin@videolan.org>
Tue, 9 Dec 2003 19:18:48 +0000 (19:18 +0000)
committerGildas Bazin <gbazin@videolan.org>
Tue, 9 Dec 2003 19:18:48 +0000 (19:18 +0000)
  This overflow was only affecting the hardware configurations where we can't use the performance counter and thus have to use GetTickCount().
  We now also check for the wrapping of the 32 bits value returned by GetTickCount() so mdate() doesn't wrap after 49.7 days.
* src/misc/win32_specific.c: call mdate() once in system_Init() so as to avoid thread safety issues while initialising the static variables used in mdate().

src/misc/mtime.c
src/misc/win32_specific.c

index 324feea0705357fca0840a1b4d3ce7779881ac95..498dc2a3087866f01230e7895ffc980cd21295ce 100644 (file)
@@ -3,7 +3,7 @@
  * Functions are prototyped in mtime.h.
  *****************************************************************************
  * Copyright (C) 1998-2001, 2003 VideoLAN
- * $Id: mtime.c,v 1.39 2003/12/03 21:50:50 sigmunau Exp $
+ * $Id: mtime.c,v 1.40 2003/12/09 19:18:48 gbazin Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *
@@ -154,9 +154,39 @@ mtime_t mdate( void )
         QueryPerformanceCounter( (LARGE_INTEGER *)&usec_time );
         return ( usec_time * 1000000 ) / freq;
     }
-
-    /* Milisecond resolution (actually, best case is about 10 ms resolution) */
-    return 1000 * GetTickCount();
+    else
+    {
+        /* Fallback on GetTickCount() which has a milisecond resolution
+         * (actually, best case is about 10 ms resolution)
+         * GetTickCount() only returns a DWORD thus will wrap after
+         * about 49.7 days so we try to detect the wrapping. */
+
+        static CRITICAL_SECTION date_lock;
+        static mtime_t i_previous_time = I64C(-1);
+        static int i_wrap_counts = -1;
+
+        if( i_wrap_counts == -1 )
+        {
+            /* Initialization */
+            i_previous_time = usec_time;
+            InitializeCriticalSection( &date_lock );
+            i_wrap_counts = 0;
+        }
+
+        EnterCriticalSection( &date_lock );
+        usec_time = I64C(1000) *
+            (i_wrap_counts * I64C(0x100000000) + GetTickCount());
+        if( i_previous_time > usec_time )
+        {
+            /* Counter wrapped */
+            i_wrap_counts++;
+            usec_time += I64C(0x100000000000);
+        }
+        i_previous_time = usec_time;
+        LeaveCriticalSection( &date_lock );
+
+        return usec_time;
+    }
 
 #else
     struct timeval tv_date;
index 4782f2059cbb0ef14cc8f7f7dc844346bb939f25..7afacde49a63832d41bdc779d92e01acdb02f3ac 100644 (file)
@@ -2,7 +2,7 @@
  * win32_specific.c: Win32 specific features
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: win32_specific.c,v 1.27 2003/12/02 12:57:36 gbazin Exp $
+ * $Id: win32_specific.c,v 1.28 2003/12/09 19:18:48 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Gildas Bazin <gbazin@netcourrier.com>
@@ -72,6 +72,9 @@ void system_Init( vlc_t *p_this, int *pi_argc, char *ppsz_argv[] )
     _fmode = _O_BINARY;
     _setmode( _fileno( stdin ), _O_BINARY ); /* Needed for pipes */
 
+    /* Call mdate() once to make sure it is initialized properly */
+    mdate();
+
     /* WinSock Library Init. */
     if( !WSAStartup( MAKEWORD( 2, 0 ), &Data ) )
     {