Commit:    b903d2d6cdf9a9efac181a21e95ea93dc8a864dd
Author:    Anatol Belski <a...@php.net>         Fri, 15 Mar 2013 19:04:40 +0100
Parents:   9350f45aca48a1ad95da5dbaca0ee8a06e46a8d6
Branches:  PHP-5.3 PHP-5.4 PHP-5.5 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=b903d2d6cdf9a9efac181a21e95ea93dc8a864dd

Log:
Backported patch for #64370

Bugs:
https://bugs.php.net/64370

Changed paths:
  M  NEWS
  A  ext/standard/tests/bug64370_var1.phpt
  A  ext/standard/tests/bug64370_var2.phpt
  M  win32/globals.c
  M  win32/php_win32_globals.h
  M  win32/time.c


Diff:
diff --git a/NEWS b/NEWS
index fb877c0..41f5eab 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 0000000..ff64d61
--- /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 0000000..d0d3590
--- /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 1bbb3b4..b381cc1 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 1686e5d..b2b07f6 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 391a8a8..77e4504 100644
--- a/win32/time.c
+++ b/win32/time.c
@@ -12,13 +12,6 @@
 
 /* $Id$ */
 
- /**
-  *
-  * 04-Feb-2001
-  *   - Added patch by "Vanhanen, Reijo" <reijo.vanha...@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) {


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to