summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2013-03-15 19:04:40 +0100
committerAnatol Belski <ab@php.net>2013-03-15 19:04:40 +0100
commitb903d2d6cdf9a9efac181a21e95ea93dc8a864dd (patch)
tree9799638a5f4aa2f8839b1ab00a3a787286db7456
parent9350f45aca48a1ad95da5dbaca0ee8a06e46a8d6 (diff)
downloadphp-git-b903d2d6cdf9a9efac181a21e95ea93dc8a864dd.tar.gz
Backported patch for #64370
-rw-r--r--NEWS5
-rw-r--r--ext/standard/tests/bug64370_var1.phpt26
-rw-r--r--ext/standard/tests/bug64370_var2.phpt23
-rw-r--r--win32/globals.c2
-rw-r--r--win32/php_win32_globals.h4
-rw-r--r--win32/time.c133
6 files changed, 96 insertions, 97 deletions
diff --git a/NEWS b/NEWS
index fb877c0185..41f5eab4e7 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,11 @@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 2013, PHP 5.3.24
+
+- Core
+ . Fixed bug #64370 (microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT']).
+ (Anatol)
+
- PCRE:
. Merged PCRE 8.32). (Anatol)
diff --git a/ext/standard/tests/bug64370_var1.phpt b/ext/standard/tests/bug64370_var1.phpt
new file mode 100644
index 0000000000..ff64d61616
--- /dev/null
+++ b/ext/standard/tests/bug64370_var1.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Test bug #64370 microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT']
+--SKIPIF--
+<?php
+ if (PHP_MAJOR_VERSION < 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4)) {
+ die('skip PHP 5.4+ only');
+ }
+--FILE--
+<?php
+echo "\$_SERVER['REQUEST_TIME']: {$_SERVER['REQUEST_TIME']}\n";
+echo "\$_SERVER['REQUEST_TIME_FLOAT']: {$_SERVER['REQUEST_TIME_FLOAT']}\n";
+echo "time(): " . time() . "\n";
+echo "microtime(true): " . microtime(true) . "\n";
+$d = (microtime(true)-$_SERVER['REQUEST_TIME_FLOAT'])*1000;
+echo "created in $d ms\n";
+echo ((bool)($d >= 0)) . "\n";
+?>
+===DONE===
+--EXPECTF--
+$_SERVER['REQUEST_TIME']: %d
+$_SERVER['REQUEST_TIME_FLOAT']: %f
+time(): %d
+microtime(true): %f
+created in %f ms
+1
+===DONE===
diff --git a/ext/standard/tests/bug64370_var2.phpt b/ext/standard/tests/bug64370_var2.phpt
new file mode 100644
index 0000000000..d0d3590ea7
--- /dev/null
+++ b/ext/standard/tests/bug64370_var2.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Test bug #64370 sequential microtime(true) calls
+--FILE--
+<?php
+
+$i = 0;
+while(100000 > $i++) {
+ $m0 = microtime(true);
+ $m1 = microtime(true);
+ $d = $m1 - $m0;
+
+ /*echo "$d\n";*/
+
+ if ($d < 0) {
+ die("failed in {$i}th iteration");
+ }
+}
+echo "ok\n";
+?>
+===DONE===
+--EXPECT--
+ok
+===DONE===
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) {