Skip to content

Commit b903d2d

Browse files
committed
Backported patch for #64370
1 parent 9350f45 commit b903d2d

File tree

6 files changed

+96
-97
lines changed

6 files changed

+96
-97
lines changed

NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? 2013, PHP 5.3.24
4+
5+
- Core
6+
. Fixed bug #64370 (microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT']).
7+
(Anatol)
8+
49
- PCRE:
510
. Merged PCRE 8.32). (Anatol)
611

ext/standard/tests/bug64370_var1.phpt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Test bug #64370 microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT']
3+
--SKIPIF--
4+
<?php
5+
if (PHP_MAJOR_VERSION < 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4)) {
6+
die('skip PHP 5.4+ only');
7+
}
8+
--FILE--
9+
<?php
10+
echo "\$_SERVER['REQUEST_TIME']: {$_SERVER['REQUEST_TIME']}\n";
11+
echo "\$_SERVER['REQUEST_TIME_FLOAT']: {$_SERVER['REQUEST_TIME_FLOAT']}\n";
12+
echo "time(): " . time() . "\n";
13+
echo "microtime(true): " . microtime(true) . "\n";
14+
$d = (microtime(true)-$_SERVER['REQUEST_TIME_FLOAT'])*1000;
15+
echo "created in $d ms\n";
16+
echo ((bool)($d >= 0)) . "\n";
17+
?>
18+
===DONE===
19+
--EXPECTF--
20+
$_SERVER['REQUEST_TIME']: %d
21+
$_SERVER['REQUEST_TIME_FLOAT']: %f
22+
time(): %d
23+
microtime(true): %f
24+
created in %f ms
25+
1
26+
===DONE===

ext/standard/tests/bug64370_var2.phpt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
Test bug #64370 sequential microtime(true) calls
3+
--FILE--
4+
<?php
5+
6+
$i = 0;
7+
while(100000 > $i++) {
8+
$m0 = microtime(true);
9+
$m1 = microtime(true);
10+
$d = $m1 - $m0;
11+
12+
/*echo "$d\n";*/
13+
14+
if ($d < 0) {
15+
die("failed in {$i}th iteration");
16+
}
17+
}
18+
echo "ok\n";
19+
?>
20+
===DONE===
21+
--EXPECT--
22+
ok
23+
===DONE===

win32/globals.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,6 @@ PHP_RSHUTDOWN_FUNCTION(win32_core_globals)
6565
;
6666

6767
closelog();
68-
wg->starttime.tv_sec = 0;
69-
wg->lasttime = 0;
7068

7169
return SUCCESS;
7270
}

win32/php_win32_globals.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@ struct _php_win32_core_globals {
3838
char *log_header;
3939
HANDLE log_source;
4040

41-
/* time */
42-
struct timeval starttime;
43-
__int64 lasttime, freq;
44-
4541
HKEY registry_key;
4642
HANDLE registry_event;
4743
HashTable *registry_directories;

win32/time.c

Lines changed: 42 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,6 @@
1212

1313
/* $Id$ */
1414

15-
/**
16-
*
17-
* 04-Feb-2001
18-
* - Added patch by "Vanhanen, Reijo" <Reijo.Vanhanen@helsoft.fi>
19-
* Improves accuracy of msec
20-
*/
21-
2215
/* Include stuff ************************************************************ */
2316

2417
#include <config.w32.h>
@@ -32,98 +25,56 @@
3225
#include <errno.h>
3326
#include "php_win32_globals.h"
3427

35-
int getfilesystemtime(struct timeval *time_Info)
28+
typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime);
29+
30+
static MyGetSystemTimeAsFileTime get_time_func(void)
3631
{
37-
FILETIME ft;
38-
__int64 ff;
39-
ULARGE_INTEGER convFromft;
40-
41-
GetSystemTimeAsFileTime(&ft); /* 100 ns blocks since 01-Jan-1641 */
42-
/* resolution seems to be 0.01 sec */
43-
/*
44-
* Do not cast a pointer to a FILETIME structure to either a
45-
* ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows.
46-
* via http://technet.microsoft.com/en-us/library/ms724284(v=vs.85).aspx
47-
*/
48-
convFromft.HighPart = ft.dwHighDateTime;
49-
convFromft.LowPart = ft.dwLowDateTime;
50-
ff = convFromft.QuadPart;
51-
52-
time_Info->tv_sec = (int)(ff/(__int64)10000000-(__int64)11644473600);
53-
time_Info->tv_usec = (int)(ff % 10000000)/10;
54-
return 0;
32+
MyGetSystemTimeAsFileTime timefunc = NULL;
33+
HMODULE hMod = LoadLibrary("kernel32.dll");
34+
35+
if (hMod) {
36+
/* Max possible resolution <1us, win8/server2012 */
37+
timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimePreciseAsFileTime");
38+
39+
if(!timefunc) {
40+
/* 100ns blocks since 01-Jan-1641 */
41+
timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimeAsFileTime");
42+
}
43+
}
44+
45+
return timefunc;
5546
}
5647

57-
48+
int getfilesystemtime(struct timeval *tv)
49+
{
50+
FILETIME ft;
51+
unsigned __int64 ff = 0;
52+
MyGetSystemTimeAsFileTime timefunc;
53+
54+
timefunc = get_time_func();
55+
if (timefunc) {
56+
timefunc(&ft);
57+
} else {
58+
GetSystemTimeAsFileTime(&ft);
59+
}
60+
61+
ff |= ft.dwHighDateTime;
62+
ff <<= 32;
63+
ff |= ft.dwLowDateTime;
64+
ff /= 10; /* convert to microseconds */
65+
ff -= 11644473600000000Ui64; /* convert to unix epoch */
66+
67+
tv->tv_sec = (long)(ff / 1000000UL);
68+
tv->tv_usec = (long)(ff % 1000000UL);
69+
70+
return 0;
71+
}
5872

5973
PHPAPI int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info)
6074
{
61-
__int64 timer;
62-
LARGE_INTEGER li;
63-
BOOL b;
64-
double dt;
65-
TSRMLS_FETCH();
66-
6775
/* Get the time, if they want it */
6876
if (time_Info != NULL) {
69-
if (PW32G(starttime).tv_sec == 0) {
70-
b = QueryPerformanceFrequency(&li);
71-
if (!b) {
72-
PW32G(starttime).tv_sec = -1;
73-
}
74-
else {
75-
PW32G(freq) = li.QuadPart;
76-
b = QueryPerformanceCounter(&li);
77-
if (!b) {
78-
PW32G(starttime).tv_sec = -1;
79-
}
80-
else {
81-
getfilesystemtime(&PW32G(starttime));
82-
timer = li.QuadPart;
83-
dt = (double)timer/PW32G(freq);
84-
PW32G(starttime).tv_usec -= (int)((dt-(int)dt)*1000000);
85-
if (PW32G(starttime).tv_usec < 0) {
86-
PW32G(starttime).tv_usec += 1000000;
87-
--PW32G(starttime).tv_sec;
88-
}
89-
PW32G(starttime).tv_sec -= (int)dt;
90-
}
91-
}
92-
}
93-
if (PW32G(starttime).tv_sec > 0) {
94-
b = QueryPerformanceCounter(&li);
95-
if (!b) {
96-
PW32G(starttime).tv_sec = -1;
97-
}
98-
else {
99-
timer = li.QuadPart;
100-
if (timer < PW32G(lasttime)) {
101-
getfilesystemtime(time_Info);
102-
dt = (double)timer/PW32G(freq);
103-
PW32G(starttime) = *time_Info;
104-
PW32G(starttime).tv_usec -= (int)((dt-(int)dt)*1000000);
105-
if (PW32G(starttime).tv_usec < 0) {
106-
PW32G(starttime).tv_usec += 1000000;
107-
--PW32G(starttime).tv_sec;
108-
}
109-
PW32G(starttime).tv_sec -= (int)dt;
110-
}
111-
else {
112-
PW32G(lasttime) = timer;
113-
dt = (double)timer/PW32G(freq);
114-
time_Info->tv_sec = PW32G(starttime).tv_sec + (int)dt;
115-
time_Info->tv_usec = PW32G(starttime).tv_usec + (int)((dt-(int)dt)*1000000);
116-
if (time_Info->tv_usec >= 1000000) {
117-
time_Info->tv_usec -= 1000000;
118-
++time_Info->tv_sec;
119-
}
120-
}
121-
}
122-
}
123-
if (PW32G(starttime).tv_sec < 0) {
124-
getfilesystemtime(time_Info);
125-
}
126-
77+
getfilesystemtime(time_Info);
12778
}
12879
/* Get the timezone, if they want it */
12980
if (timezone_Info != NULL) {

0 commit comments

Comments
 (0)