diff --git a/CHANGES b/CHANGES index d0e41a5d419a00..8372bd37bf38a8 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,10 @@ Changelog +Yang Tse (9 May 2008) +- Internal time differences now use monotonic time source if available. + This also implies the removal of the winmm.lib dependency for WIN32. + Daniel Stenberg (9 May 2008) - Stefan Krause reported a busy-looping case when using the multi interface and doing CONNECT to a proxy. The app would then busy-loop until the proxy diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 1e85e25fc438a8..15781b3ea060ae 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -33,6 +33,7 @@ This release includes the following bugfixes: o microsecond resolution keys for internal splay trees o krb4 and krb5 ftp segfault o multi interface busy loop for CONNECT requests + o internal time differences now use monotonic time source if available This release includes the following known bugs: diff --git a/configure.ac b/configure.ac index 910a8d160dc867..8a5988959e7ade 100644 --- a/configure.ac +++ b/configure.ac @@ -674,36 +674,6 @@ if test x$CURL_DISABLE_LDAP != x1 ; then fi fi -dnl ********************************************************************** -dnl Check for the presence of the winmm library. -dnl ********************************************************************** - -case $host in - *-*-cygwin*) - dnl Under Cygwin, winmm exists but is not needed as WIN32 is not #defined - dnl and gettimeofday() will be used regardless of the outcome of this test. - dnl Skip this test, otherwise -lwinmm will be needlessly added to LIBS - dnl (and recorded as such in the .la file, potentially affecting downstream - dnl clients of the library.) - ;; - *) - AC_MSG_CHECKING([for timeGetTime in winmm]) - my_ac_save_LIBS=$LIBS - LIBS="-lwinmm $LIBS" - AC_TRY_LINK([#include - #include - ], - [timeGetTime();], - [ dnl worked! - AC_MSG_RESULT([yes]) - ], - [ dnl failed, restore LIBS - LIBS=$my_ac_save_LIBS - AC_MSG_RESULT(no)] - ) - ;; -esac - dnl ********************************************************************** dnl Checks for IPv6 dnl ********************************************************************** @@ -2006,6 +1976,7 @@ AC_CHECK_FUNCS( strtoll \ strcmpi \ gethostbyaddr \ gettimeofday \ + clock_gettime \ inet_addr \ inet_ntoa \ inet_pton \ diff --git a/docs/INSTALL.devcpp b/docs/INSTALL.devcpp index 8ff4144cc47ce6..ed5ed9150240f7 100644 --- a/docs/INSTALL.devcpp +++ b/docs/INSTALL.devcpp @@ -239,7 +239,7 @@ Linker Links checked. 3- Include in the white space immediately below the box referred in 2 -lcurl --lws2_32 -lwinmm. +-lws2_32. SSL Files --------- diff --git a/docs/examples/Makefile.m32 b/docs/examples/Makefile.m32 index 470061c4cf5148..5107c04fea4559 100644 --- a/docs/examples/Makefile.m32 +++ b/docs/examples/Makefile.m32 @@ -106,7 +106,7 @@ ifndef USE_LDAP_OPENLDAP curl_LDADD += -lwldap32 endif endif -curl_LDADD += -lws2_32 -lwinmm +curl_LDADD += -lws2_32 COMPILE = $(CC) $(INCLUDES) $(CFLAGS) # Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines diff --git a/lib/Makefile.Watcom b/lib/Makefile.Watcom index 8e5118ecb147dd..ed564c111cbd4a 100644 --- a/lib/Makefile.Watcom +++ b/lib/Makefile.Watcom @@ -10,7 +10,7 @@ CC = wcc386 CFLAGS = -3r -mf -d3 -hc -zff -zgf -zq -zm -zc -s -fr=con -w2 -fpi -oilrtfm -bt=nt & -bd -d+ -dWIN32 -dCURL_CA_BUNDLE=getenv("CURL_CA_BUNDLE") & - -dBUILDING_LIBCURL -dWITHOUT_MM_LIB -dHAVE_SPNEGO=1 -dENABLE_IPV6 & + -dBUILDING_LIBCURL -dHAVE_SPNEGO=1 -dENABLE_IPV6 & -dDEBUG_THREADING_GETADDRINFO -dDEBUG=1 -dCURLDEBUG -d_WIN32_WINNT=0x0501 & -dWINBERAPI=__declspec(cdecl) -dWINLDAPAPI=__declspec(cdecl) & -I. -I..\include diff --git a/lib/Makefile.m32 b/lib/Makefile.m32 index 6fd8b9b7c28d0c..615d07805a6254 100644 --- a/lib/Makefile.m32 +++ b/lib/Makefile.m32 @@ -96,7 +96,7 @@ ifndef USE_LDAP_OPENLDAP DLL_LIBS += -lwldap32 endif endif -DLL_LIBS += -lws2_32 -lwinmm +DLL_LIBS += -lws2_32 COMPILE = $(CC) $(INCLUDES) $(CFLAGS) # Makefile.inc provides the CSOURCES and HHEADERS defines diff --git a/lib/Makefile.vc6 b/lib/Makefile.vc6 index bce42a6a0a2ae0..5652cb49958c6d 100644 --- a/lib/Makefile.vc6 +++ b/lib/Makefile.vc6 @@ -66,10 +66,6 @@ WINDOWS_SDK_PATH = "C:\Program Files\Microsoft SDK" !ENDIF !ENDIF -# Use the high resolution time by default. Comment this out to use low -# resolution time and not require winmm.lib -USEMM_LIBS = YES - ############################################################# ## Nothing more to do below this line! @@ -85,13 +81,9 @@ LFLAGS = /nologo /machine:$(MACHINE) SSLLIBS = libeay32.lib ssleay32.lib ZLIBLIBSDLL= zdll.lib ZLIBLIBS = zlib.lib -!IFDEF USEMM_LIBS -WINLIBS = wsock32.lib wldap32.lib winmm.lib -!ELSE WINLIBS = wsock32.lib wldap32.lib -CFLAGS = $(CFLAGS) /DWITHOUT_MM_LIB -!ENDIF -# RSAglue.lib was formerly needed in the SSLLIBS +CFLAGS = $(CFLAGS) + CFGSET = FALSE !IFDEF WINDOWS_SSPI diff --git a/lib/config-win32ce.h b/lib/config-win32ce.h index 6c0fb411f63200..b3f6c74ff6474f 100644 --- a/lib/config-win32ce.h +++ b/lib/config-win32ce.h @@ -350,7 +350,6 @@ #define CURL_DISABLE_FILE 1 #define CURL_DISABLE_TELNET 1 #define CURL_DISABLE_LDAP 1 -#define WITHOUT_MM_LIB 1 #ifdef HAVE_WINDOWS_H # ifndef WIN32_LEAN_AND_MEAN diff --git a/lib/msvcproj.head b/lib/msvcproj.head index cfc7b5aa8cbd09..7035980599c893 100644 --- a/lib/msvcproj.head +++ b/lib/msvcproj.head @@ -54,7 +54,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib ws2_32.lib wldap32.lib winmm.lib /nologo /dll /map /debug /machine:I386 /out:"Release/libcurl.dll" +# ADD LINK32 kernel32.lib ws2_32.lib wldap32.lib /nologo /dll /map /debug /machine:I386 /out:"Release/libcurl.dll" !ELSEIF "$(CFG)" == "curllib - Win32 Debug" @@ -81,7 +81,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib ws2_32.lib wldap32.lib winmm.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug/libcurl.dll" /pdbtype:sept +# ADD LINK32 kernel32.lib ws2_32.lib wldap32.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug/libcurl.dll" /pdbtype:sept # SUBTRACT LINK32 /nodefaultlib !ENDIF diff --git a/lib/select.c b/lib/select.c index c305bc9fa45177..847933ee9c4c8e 100644 --- a/lib/select.c +++ b/lib/select.c @@ -184,7 +184,7 @@ int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd, return r; } - /* Avoid initial timestamp, avoid gettimeofday() call, when elapsed + /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed time in this function does not need to be measured. This happens when function is called with a zero timeout or a negative timeout value indicating a blocking call should be performed. */ @@ -368,7 +368,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms) return r; } - /* Avoid initial timestamp, avoid gettimeofday() call, when elapsed + /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed time in this function does not need to be measured. This happens when function is called with a zero timeout or a negative timeout value indicating a blocking call should be performed. */ diff --git a/lib/timeval.c b/lib/timeval.c index bb9c0a174d9e73..b36633384d654a 100644 --- a/lib/timeval.c +++ b/lib/timeval.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -23,69 +23,70 @@ #include "timeval.h" -#ifndef HAVE_GETTIMEOFDAY +#if defined(WIN32) && !defined(MSDOS) -#ifdef WIN32 -#include - -static int gettimeofday(struct timeval *tp, void *nothing) +struct timeval curlx_tvnow(void) { -#ifdef WITHOUT_MM_LIB - SYSTEMTIME st; - time_t tt; - struct tm tmtm; - /* mktime converts local to UTC */ - GetLocalTime (&st); - tmtm.tm_sec = st.wSecond; - tmtm.tm_min = st.wMinute; - tmtm.tm_hour = st.wHour; - tmtm.tm_mday = st.wDay; - tmtm.tm_mon = st.wMonth - 1; - tmtm.tm_year = st.wYear - 1900; - tmtm.tm_isdst = -1; - tt = mktime (&tmtm); - tp->tv_sec = tt; - tp->tv_usec = st.wMilliseconds * 1000; -#else - /** - ** The earlier time calculations using GetLocalTime - ** had a time resolution of 10ms.The timeGetTime, part - ** of multimedia apis offer a better time resolution - ** of 1ms.Need to link against winmm.lib for this - **/ - unsigned long Ticks = 0; - unsigned long Sec =0; - unsigned long Usec = 0; - Ticks = timeGetTime(); - - Sec = Ticks/1000; - Usec = (Ticks - (Sec*1000))*1000; - tp->tv_sec = Sec; - tp->tv_usec = Usec; -#endif /* WITHOUT_MM_LIB */ - (void)nothing; - return 0; + /* + ** GetTickCount() is available on _all_ Windows versions from W95 up + ** to nowadays. Returns milliseconds elapsed since last system boot, + ** increases monotonically and wraps once 49.7 days have elapsed. + */ + struct timeval now; + DWORD milliseconds = GetTickCount(); + now.tv_sec = milliseconds / 1000; + now.tv_usec = (milliseconds % 1000) * 1000; + return now; } -#else /* WIN32 */ -/* non-win32 version of Curl_gettimeofday() */ -static int gettimeofday(struct timeval *tp, void *nothing) + +#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) + +struct timeval curlx_tvnow(void) { - (void)nothing; /* we don't support specific time-zones */ - tp->tv_sec = (long)time(NULL); - tp->tv_usec = 0; - return 0; + /* + ** clock_gettime() is granted to be increased monotonically when the + ** monotonic clock is queried. Time starting point is unspecified, it + ** could be the system start-up time, the Epoch, or something else, + ** in any case the time starting point does not change once that the + ** system has started up. + */ + struct timeval now; + struct timespec tsnow; + (void)clock_gettime(CLOCK_MONOTONIC, &tsnow) + now.tv_sec = tsnow.tv_sec; + now.tv_usec = tsnow.tv_nsec / 1000; + return now; } -#endif /* WIN32 */ -#endif /* HAVE_GETTIMEOFDAY */ -/* Return the current time in a timeval struct */ +#elif defined(HAVE_GETTIMEOFDAY) + struct timeval curlx_tvnow(void) { + /* + ** gettimeofday() is not granted to be increased monotonically, due to + ** clock drifting and external source time synchronization it can jump + ** forward or backward in time. + */ struct timeval now; (void)gettimeofday(&now, NULL); return now; } +#else + +struct timeval curlx_tvnow(void) +{ + /* + ** time() returns the value of time in seconds since the Epoch. + */ + struct timeval now; + now.tv_sec = (long)time(NULL); + now.tv_usec = 0; + return now; +} + +#endif + /* * Make sure that the first argument is the more recent time, as otherwise * we'll get a weird negative time-diff back... diff --git a/src/Makefile.Watcom b/src/Makefile.Watcom index 8f75233a670dcb..942443848cf7a0 100644 --- a/src/Makefile.Watcom +++ b/src/Makefile.Watcom @@ -7,7 +7,7 @@ CC = wcc386 CFLAGS = -3r -mf -d3 -hc -zff -zgf -zq -zm -s -fr=con -w2 -fpi -oilrtfm & - -bt=nt -d+ -dWIN32 -dHAVE_STRTOLL -dWITHOUT_MM_LIB & + -bt=nt -d+ -dWIN32 -dHAVE_STRTOLL & -dSIZEOF_CURL_OFF_T=8 -dCURLDEBUG -dENABLE_IPV6 -dHAVE_WINSOCK2_H & -I..\include -I..\lib diff --git a/src/Makefile.m32 b/src/Makefile.m32 index 32817e91593c3d..3ecd999710943d 100644 --- a/src/Makefile.m32 +++ b/src/Makefile.m32 @@ -104,7 +104,7 @@ ifndef USE_LDAP_OPENLDAP curl_LDADD += -lwldap32 endif endif -curl_LDADD += -lws2_32 -lwinmm +curl_LDADD += -lws2_32 COMPILE = $(CC) $(INCLUDES) $(CFLAGS) # Makefile.inc provides the CSOURCES and HHEADERS defines diff --git a/src/Makefile.vc6 b/src/Makefile.vc6 index 2332422525a6fe..49438d1e381e01 100644 --- a/src/Makefile.vc6 +++ b/src/Makefile.vc6 @@ -10,8 +10,6 @@ ## Comments to: Troy Engel ## Updated by: Craig Davison ## release-ssl added by Miklos Nemeth -## winmm.lib added by Miklos Nemeth to -## support timeGetTime() in curlutil.c # ############################################################# @@ -221,8 +219,8 @@ LFLAGS = $(LFLAGS) $(SSL_IMP_LFLAGS) $(ZLIB_LFLAGS) !ENDIF -LINKLIBS = $(LINKLIBS) wsock32.lib wldap32.lib winmm.lib -LINKLIBS_DEBUG = $(LINKLIBS_DEBUG) wsock32.lib wldap32.lib winmm.lib +LINKLIBS = $(LINKLIBS) wsock32.lib wldap32.lib +LINKLIBS_DEBUG = $(LINKLIBS_DEBUG) wsock32.lib wldap32.lib all : release diff --git a/src/curlutil.c b/src/curlutil.c index 0394d80e2b68de..12a7d2e06510cb 100644 --- a/src/curlutil.c +++ b/src/curlutil.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -25,69 +25,70 @@ #include "curlutil.h" -#ifndef HAVE_GETTIMEOFDAY +#if defined(WIN32) && !defined(MSDOS) -#ifdef WIN32 -#include - -static int gettimeofday(struct timeval *tp, void *nothing) +struct timeval cutil_tvnow(void) { -#ifdef WITHOUT_MM_LIB - SYSTEMTIME st; - time_t tt; - struct tm tmtm; - /* mktime converts local to UTC */ - GetLocalTime (&st); - tmtm.tm_sec = st.wSecond; - tmtm.tm_min = st.wMinute; - tmtm.tm_hour = st.wHour; - tmtm.tm_mday = st.wDay; - tmtm.tm_mon = st.wMonth - 1; - tmtm.tm_year = st.wYear - 1900; - tmtm.tm_isdst = -1; - tt = mktime (&tmtm); - tp->tv_sec = tt; - tp->tv_usec = st.wMilliseconds * 1000; -#else - /** - ** The earlier time calculations using GetLocalTime - ** had a time resolution of 10ms.The timeGetTime, part - ** of multimedia apis offer a better time resolution - ** of 1ms.Need to link against winmm.lib for this - **/ - unsigned long Ticks = 0; - unsigned long Sec =0; - unsigned long Usec = 0; - Ticks = timeGetTime(); - - Sec = Ticks/1000; - Usec = (Ticks - (Sec*1000))*1000; - tp->tv_sec = Sec; - tp->tv_usec = Usec; -#endif /* WITHOUT_MM_LIB */ - (void)nothing; - return 0; + /* + ** GetTickCount() is available on _all_ Windows versions from W95 up + ** to nowadays. Returns milliseconds elapsed since last system boot, + ** increases monotonically and wraps once 49.7 days have elapsed. + */ + struct timeval now; + DWORD milliseconds = GetTickCount(); + now.tv_sec = milliseconds / 1000; + now.tv_usec = (milliseconds % 1000) * 1000; + return now; } -#else /* WIN32 */ -/* non-win32 version of Curl_gettimeofday() */ -static int gettimeofday(struct timeval *tp, void *nothing) + +#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) + +struct timeval cutil_tvnow(void) { - (void)nothing; /* we don't support specific time-zones */ - tp->tv_sec = (long)time(NULL); - tp->tv_usec = 0; - return 0; + /* + ** clock_gettime() is granted to be increased monotonically when the + ** monotonic clock is queried. Time starting point is unspecified, it + ** could be the system start-up time, the Epoch, or something else, + ** in any case the time starting point does not change once that the + ** system has started up. + */ + struct timeval now; + struct timespec tsnow; + (void)clock_gettime(CLOCK_MONOTONIC, &tsnow) + now.tv_sec = tsnow.tv_sec; + now.tv_usec = tsnow.tv_nsec / 1000; + return now; } -#endif /* WIN32 */ -#endif /* HAVE_GETTIMEOFDAY */ -/* Return the current time in a timeval struct */ +#elif defined(HAVE_GETTIMEOFDAY) + struct timeval cutil_tvnow(void) { + /* + ** gettimeofday() is not granted to be increased monotonically, due to + ** clock drifting and external source time synchronization it can jump + ** forward or backward in time. + */ struct timeval now; (void)gettimeofday(&now, NULL); return now; } +#else + +struct timeval cutil_tvnow(void) +{ + /* + ** time() returns the value of time in seconds since the Epoch. + */ + struct timeval now; + now.tv_sec = (long)time(NULL); + now.tv_usec = 0; + return now; +} + +#endif + /* * Make sure that the first argument is the more recent time, as otherwise * we'll get a weird negative time-diff back... diff --git a/tests/libtest/testutil.c b/tests/libtest/testutil.c index 146660c71342bc..8ed2b2f08459e6 100644 --- a/tests/libtest/testutil.c +++ b/tests/libtest/testutil.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -25,69 +25,70 @@ #include "testutil.h" -#ifndef HAVE_GETTIMEOFDAY +#if defined(WIN32) && !defined(MSDOS) -#ifdef WIN32 -#include - -static int gettimeofday(struct timeval *tp, void *nothing) +struct timeval tutil_tvnow(void) { -#ifdef WITHOUT_MM_LIB - SYSTEMTIME st; - time_t tt; - struct tm tmtm; - /* mktime converts local to UTC */ - GetLocalTime (&st); - tmtm.tm_sec = st.wSecond; - tmtm.tm_min = st.wMinute; - tmtm.tm_hour = st.wHour; - tmtm.tm_mday = st.wDay; - tmtm.tm_mon = st.wMonth - 1; - tmtm.tm_year = st.wYear - 1900; - tmtm.tm_isdst = -1; - tt = mktime (&tmtm); - tp->tv_sec = tt; - tp->tv_usec = st.wMilliseconds * 1000; -#else - /** - ** The earlier time calculations using GetLocalTime - ** had a time resolution of 10ms.The timeGetTime, part - ** of multimedia apis offer a better time resolution - ** of 1ms.Need to link against winmm.lib for this - **/ - unsigned long Ticks = 0; - unsigned long Sec =0; - unsigned long Usec = 0; - Ticks = timeGetTime(); - - Sec = Ticks/1000; - Usec = (Ticks - (Sec*1000))*1000; - tp->tv_sec = Sec; - tp->tv_usec = Usec; -#endif /* WITHOUT_MM_LIB */ - (void)nothing; - return 0; + /* + ** GetTickCount() is available on _all_ Windows versions from W95 up + ** to nowadays. Returns milliseconds elapsed since last system boot, + ** increases monotonically and wraps once 49.7 days have elapsed. + */ + struct timeval now; + DWORD milliseconds = GetTickCount(); + now.tv_sec = milliseconds / 1000; + now.tv_usec = (milliseconds % 1000) * 1000; + return now; } -#else /* WIN32 */ -/* non-win32 version of Curl_gettimeofday() */ -static int gettimeofday(struct timeval *tp, void *nothing) + +#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) + +struct timeval tutil_tvnow(void) { - (void)nothing; /* we don't support specific time-zones */ - tp->tv_sec = (long)time(NULL); - tp->tv_usec = 0; - return 0; + /* + ** clock_gettime() is granted to be increased monotonically when the + ** monotonic clock is queried. Time starting point is unspecified, it + ** could be the system start-up time, the Epoch, or something else, + ** in any case the time starting point does not change once that the + ** system has started up. + */ + struct timeval now; + struct timespec tsnow; + (void)clock_gettime(CLOCK_MONOTONIC, &tsnow) + now.tv_sec = tsnow.tv_sec; + now.tv_usec = tsnow.tv_nsec / 1000; + return now; } -#endif /* WIN32 */ -#endif /* HAVE_GETTIMEOFDAY */ -/* Return the current time in a timeval struct */ +#elif defined(HAVE_GETTIMEOFDAY) + struct timeval tutil_tvnow(void) { + /* + ** gettimeofday() is not granted to be increased monotonically, due to + ** clock drifting and external source time synchronization it can jump + ** forward or backward in time. + */ struct timeval now; (void)gettimeofday(&now, NULL); return now; } +#else + +struct timeval tutil_tvnow(void) +{ + /* + ** time() returns the value of time in seconds since the Epoch. + */ + struct timeval now; + now.tv_sec = (long)time(NULL); + now.tv_usec = 0; + return now; +} + +#endif + /* * Make sure that the first argument is the more recent time, as otherwise * we'll get a weird negative time-diff back...