diff options
author | Anatol Belski <ab@php.net> | 2013-03-11 16:04:37 +0100 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2013-03-11 16:04:37 +0100 |
commit | 8aaa09636a3efee7d6e92103dad1ae2c1d137e72 (patch) | |
tree | d7fb795a4282ba5ed51a5d1e1ae452f44259bb48 /win32 | |
parent | 4573405c5dd6686bbe443497dfad84de13ac5cc7 (diff) | |
download | php-git-8aaa09636a3efee7d6e92103dad1ae2c1d137e72.tar.gz |
Fixed bug #64370 (microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT'])
Diffstat (limited to 'win32')
-rw-r--r-- | win32/globals.c | 2 | ||||
-rw-r--r-- | win32/php_win32_globals.h | 4 | ||||
-rw-r--r-- | win32/time.c | 133 |
3 files changed, 42 insertions, 97 deletions
diff --git a/win32/globals.c b/win32/globals.c index 1bbb3b4481..b381cc1237 100644 --- a/win32/globals.c +++ b/win32/globals.c @@ -65,8 +65,6 @@ PHP_RSHUTDOWN_FUNCTION(win32_core_globals) ; closelog(); - wg->starttime.tv_sec = 0; - wg->lasttime = 0; return SUCCESS; } diff --git a/win32/php_win32_globals.h b/win32/php_win32_globals.h index 1686e5df63..b2b07f68e1 100644 --- a/win32/php_win32_globals.h +++ b/win32/php_win32_globals.h @@ -38,10 +38,6 @@ struct _php_win32_core_globals { char *log_header; HANDLE log_source; - /* time */ - struct timeval starttime; - __int64 lasttime, freq; - HKEY registry_key; HANDLE registry_event; HashTable *registry_directories; diff --git a/win32/time.c b/win32/time.c index 391a8a81e9..77e4504cd1 100644 --- a/win32/time.c +++ b/win32/time.c @@ -12,13 +12,6 @@ /* $Id$ */ - /** - * - * 04-Feb-2001 - * - Added patch by "Vanhanen, Reijo" <Reijo.Vanhanen@helsoft.fi> - * Improves accuracy of msec - */ - /* Include stuff ************************************************************ */ #include <config.w32.h> @@ -32,98 +25,56 @@ #include <errno.h> #include "php_win32_globals.h" -int getfilesystemtime(struct timeval *time_Info) +typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime); + +static MyGetSystemTimeAsFileTime get_time_func(void) { - FILETIME ft; - __int64 ff; - ULARGE_INTEGER convFromft; - - GetSystemTimeAsFileTime(&ft); /* 100 ns blocks since 01-Jan-1641 */ - /* resolution seems to be 0.01 sec */ - /* - * Do not cast a pointer to a FILETIME structure to either a - * ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows. - * via http://technet.microsoft.com/en-us/library/ms724284(v=vs.85).aspx - */ - convFromft.HighPart = ft.dwHighDateTime; - convFromft.LowPart = ft.dwLowDateTime; - ff = convFromft.QuadPart; - - time_Info->tv_sec = (int)(ff/(__int64)10000000-(__int64)11644473600); - time_Info->tv_usec = (int)(ff % 10000000)/10; - return 0; + MyGetSystemTimeAsFileTime timefunc = NULL; + HMODULE hMod = LoadLibrary("kernel32.dll"); + + if (hMod) { + /* Max possible resolution <1us, win8/server2012 */ + timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimePreciseAsFileTime"); + + if(!timefunc) { + /* 100ns blocks since 01-Jan-1641 */ + timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimeAsFileTime"); + } + } + + return timefunc; } - +int getfilesystemtime(struct timeval *tv) +{ + FILETIME ft; + unsigned __int64 ff = 0; + MyGetSystemTimeAsFileTime timefunc; + + timefunc = get_time_func(); + if (timefunc) { + timefunc(&ft); + } else { + GetSystemTimeAsFileTime(&ft); + } + + ff |= ft.dwHighDateTime; + ff <<= 32; + ff |= ft.dwLowDateTime; + ff /= 10; /* convert to microseconds */ + ff -= 11644473600000000Ui64; /* convert to unix epoch */ + + tv->tv_sec = (long)(ff / 1000000UL); + tv->tv_usec = (long)(ff % 1000000UL); + + return 0; +} PHPAPI int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info) { - __int64 timer; - LARGE_INTEGER li; - BOOL b; - double dt; - TSRMLS_FETCH(); - /* Get the time, if they want it */ if (time_Info != NULL) { - if (PW32G(starttime).tv_sec == 0) { - b = QueryPerformanceFrequency(&li); - if (!b) { - PW32G(starttime).tv_sec = -1; - } - else { - PW32G(freq) = li.QuadPart; - b = QueryPerformanceCounter(&li); - if (!b) { - PW32G(starttime).tv_sec = -1; - } - else { - getfilesystemtime(&PW32G(starttime)); - timer = li.QuadPart; - dt = (double)timer/PW32G(freq); - PW32G(starttime).tv_usec -= (int)((dt-(int)dt)*1000000); - if (PW32G(starttime).tv_usec < 0) { - PW32G(starttime).tv_usec += 1000000; - --PW32G(starttime).tv_sec; - } - PW32G(starttime).tv_sec -= (int)dt; - } - } - } - if (PW32G(starttime).tv_sec > 0) { - b = QueryPerformanceCounter(&li); - if (!b) { - PW32G(starttime).tv_sec = -1; - } - else { - timer = li.QuadPart; - if (timer < PW32G(lasttime)) { - getfilesystemtime(time_Info); - dt = (double)timer/PW32G(freq); - PW32G(starttime) = *time_Info; - PW32G(starttime).tv_usec -= (int)((dt-(int)dt)*1000000); - if (PW32G(starttime).tv_usec < 0) { - PW32G(starttime).tv_usec += 1000000; - --PW32G(starttime).tv_sec; - } - PW32G(starttime).tv_sec -= (int)dt; - } - else { - PW32G(lasttime) = timer; - dt = (double)timer/PW32G(freq); - time_Info->tv_sec = PW32G(starttime).tv_sec + (int)dt; - time_Info->tv_usec = PW32G(starttime).tv_usec + (int)((dt-(int)dt)*1000000); - if (time_Info->tv_usec >= 1000000) { - time_Info->tv_usec -= 1000000; - ++time_Info->tv_sec; - } - } - } - } - if (PW32G(starttime).tv_sec < 0) { - getfilesystemtime(time_Info); - } - + getfilesystemtime(time_Info); } /* Get the timezone, if they want it */ if (timezone_Info != NULL) { |