passenger 5.0.26 → 5.0.27
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG +17 -0
- data/CONTRIBUTORS +1 -0
- data/build/cxx_dependency_map.rb +113 -157
- data/build/cxx_tests.rb +8 -1
- data/src/agent/Core/ApplicationPool/TestSession.h +5 -1
- data/src/agent/Core/Controller/CheckoutSession.cpp +1 -1
- data/src/agent/Core/Controller/ForwardResponse.cpp +9 -0
- data/src/agent/Core/Controller/InternalUtils.cpp +9 -1
- data/src/agent/Core/Controller/SendRequest.cpp +13 -7
- data/src/agent/Core/Controller/StateInspectionAndConfiguration.cpp +3 -2
- data/src/agent/Core/CoreMain.cpp +3 -0
- data/src/agent/Core/SpawningKit/SmartSpawner.h +1 -1
- data/src/agent/Core/SpawningKit/Spawner.h +2 -2
- data/src/agent/Core/UnionStation/StopwatchLog.h +3 -4
- data/src/agent/Shared/Base.cpp +32 -0
- data/src/agent/Shared/Base.h +2 -0
- data/src/agent/UstRouter/UstRouterMain.cpp +3 -0
- data/src/agent/Watchdog/AgentWatcher.cpp +1 -3
- data/src/agent/Watchdog/WatchdogMain.cpp +31 -6
- data/src/apache2_module/Hooks.cpp +2 -2
- data/src/cxx_supportlib/BackgroundEventLoop.cpp +12 -2
- data/src/cxx_supportlib/Constants.h +1 -1
- data/src/cxx_supportlib/DataStructures/LString.cpp +39 -0
- data/src/cxx_supportlib/DataStructures/LString.h +35 -6
- data/src/cxx_supportlib/FileDescriptor.h +3 -1
- data/src/cxx_supportlib/Integrations/LibevJsonUtils.h +92 -0
- data/src/cxx_supportlib/ResourceLocator.h +10 -8
- data/src/cxx_supportlib/ServerKit/CookieUtils.h +4 -0
- data/src/cxx_supportlib/ServerKit/FileBufferedChannel.h +2 -0
- data/src/cxx_supportlib/ServerKit/HttpServer.h +6 -2
- data/src/cxx_supportlib/Utils.cpp +4 -5
- data/src/cxx_supportlib/Utils.h +2 -2
- data/src/cxx_supportlib/Utils/IOUtils.cpp +1 -1
- data/src/cxx_supportlib/Utils/JsonUtils.h +12 -10
- data/src/cxx_supportlib/Utils/MessagePassing.h +4 -4
- data/src/cxx_supportlib/Utils/StrIntUtils.cpp +7 -3
- data/src/cxx_supportlib/Utils/SystemTime.cpp +15 -4
- data/src/cxx_supportlib/Utils/SystemTime.h +228 -54
- data/src/cxx_supportlib/Utils/Timer.h +14 -41
- data/src/cxx_supportlib/WatchdogLauncher.h +1 -1
- data/src/cxx_supportlib/vendor-copy/libuv/Makefile.in +198 -59
- data/src/cxx_supportlib/vendor-copy/libuv/autom4te.cache/output.0 +15477 -0
- data/src/cxx_supportlib/vendor-copy/libuv/autom4te.cache/output.1 +15477 -0
- data/src/cxx_supportlib/vendor-copy/libuv/autom4te.cache/requests +324 -0
- data/src/cxx_supportlib/vendor-copy/libuv/autom4te.cache/traces.0 +3105 -0
- data/src/cxx_supportlib/vendor-copy/libuv/autom4te.cache/traces.1 +703 -0
- data/src/cxx_supportlib/vendor-copy/libuv/configure +115 -12
- data/src/cxx_supportlib/vendor-copy/libuv/ltmain.sh +15 -8
- data/src/cxx_supportlib/vendor-copy/libuv/m4/ltversion.m4 +5 -5
- data/src/cxx_supportlib/vendor-modified/psg_sysqueue.h +1 -0
- data/src/nginx_module/ngx_http_passenger_module.c +1 -1
- data/src/nodejs_supportlib/phusion_passenger/ustreporter.js +1 -1
- data/src/ruby_native_extension/passenger_native_support.c +1 -1
- data/src/ruby_supportlib/phusion_passenger.rb +15 -1
- data/src/ruby_supportlib/phusion_passenger/common_library.rb +4 -0
- data/src/ruby_supportlib/phusion_passenger/packaging.rb +1 -0
- data/src/ruby_supportlib/phusion_passenger/ruby_core_io_enhancements.rb +5 -20
- metadata +9 -2
@@ -286,11 +286,10 @@ resolveSymlink(const StaticString &path) {
|
|
286
286
|
|
287
287
|
string
|
288
288
|
extractDirName(const StaticString &path) {
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
return result_string;
|
289
|
+
DynamicBuffer pathCopy(path.size() + 1);
|
290
|
+
memcpy(pathCopy.data, path.data(), path.size());
|
291
|
+
pathCopy.data[path.size()] = '\0';
|
292
|
+
return string(dirname(pathCopy.data));
|
294
293
|
}
|
295
294
|
|
296
295
|
StaticString
|
data/src/cxx_supportlib/Utils.h
CHANGED
@@ -178,8 +178,8 @@ string canonicalizePath(const string &path);
|
|
178
178
|
string resolveSymlink(const StaticString &path);
|
179
179
|
|
180
180
|
/**
|
181
|
-
* Given a path, extracts its directory name.
|
182
|
-
*
|
181
|
+
* Given a path, extracts its directory name. 'path' does not
|
182
|
+
* have to be NULL terminated.
|
183
183
|
*
|
184
184
|
* @ingroup Support
|
185
185
|
*/
|
@@ -208,27 +208,29 @@ timeToJson(unsigned long long timestamp, unsigned long long now = 0) {
|
|
208
208
|
}
|
209
209
|
|
210
210
|
Json::Value doc;
|
211
|
-
time_t
|
212
|
-
char
|
211
|
+
time_t wallClockTime = (time_t) (timestamp / 1000000ull);
|
212
|
+
char wallClockTimeStr[32];
|
213
213
|
size_t len;
|
214
214
|
|
215
215
|
if (now == 0) {
|
216
216
|
now = SystemTime::getUsec();
|
217
217
|
}
|
218
218
|
|
219
|
-
|
220
|
-
|
221
|
-
ctime_r(&time, buf);
|
222
|
-
len = strlen(buf);
|
219
|
+
ctime_r(&wallClockTime, wallClockTimeStr);
|
220
|
+
len = strlen(wallClockTimeStr);
|
223
221
|
if (len > 0) {
|
224
222
|
// Get rid of trailing newline
|
225
|
-
|
223
|
+
wallClockTimeStr[len - 1] = '\0';
|
226
224
|
}
|
227
|
-
|
225
|
+
|
226
|
+
doc["timestamp"] = timestamp / 1000000.0;
|
227
|
+
doc["local"] = wallClockTimeStr;
|
228
228
|
if (timestamp > now) {
|
229
|
-
doc["
|
229
|
+
doc["relative_timestamp"] = (timestamp - now) / 1000000.0;
|
230
|
+
doc["relative"] = distanceOfTimeInWords(wallClockTime, now / 1000000ull) + " from now";
|
230
231
|
} else {
|
231
|
-
doc["
|
232
|
+
doc["relative_timestamp"] = (now - timestamp) / -1000000.0;
|
233
|
+
doc["relative"] = distanceOfTimeInWords(wallClockTime, now / 1000000ull) + " ago";
|
232
234
|
}
|
233
235
|
|
234
236
|
return doc;
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2012-
|
3
|
+
* Copyright (c) 2012-2016 Phusion Holding B.V.
|
4
4
|
*
|
5
5
|
* "Passenger", "Phusion Passenger" and "Union Station" are registered
|
6
6
|
* trademarks of Phusion Holding B.V.
|
@@ -183,7 +183,7 @@ class MessageBox: public boost::enable_shared_from_this<MessageBox> {
|
|
183
183
|
}
|
184
184
|
|
185
185
|
void substractTimePassed(unsigned long long *timeout, unsigned long long beginTime) {
|
186
|
-
unsigned long long now = SystemTime::
|
186
|
+
unsigned long long now = SystemTime::getMonotonicUsec();
|
187
187
|
unsigned long long diff;
|
188
188
|
if (now > beginTime) {
|
189
189
|
diff = now - beginTime;
|
@@ -224,7 +224,7 @@ public:
|
|
224
224
|
posix_time::ptime deadline;
|
225
225
|
unsigned long long beginTime = 0; // Shut up compiler warning.
|
226
226
|
if (timeout != NULL) {
|
227
|
-
beginTime = SystemTime::
|
227
|
+
beginTime = SystemTime::getMonotonicUsec();
|
228
228
|
deadline = posix_time::microsec_clock::local_time() +
|
229
229
|
posix_time::microsec(*timeout);
|
230
230
|
}
|
@@ -263,7 +263,7 @@ public:
|
|
263
263
|
posix_time::ptime deadline;
|
264
264
|
unsigned long long beginTime = 0; // Shut up compiler warning.
|
265
265
|
if (timeout != NULL) {
|
266
|
-
beginTime = SystemTime::
|
266
|
+
beginTime = SystemTime::getMonotonicUsec();
|
267
267
|
deadline = posix_time::microsec_clock::local_time() +
|
268
268
|
posix_time::microsec(*timeout);
|
269
269
|
}
|
@@ -654,9 +654,13 @@ escapeHTML(const StaticString &input) {
|
|
654
654
|
if (ch & 128) {
|
655
655
|
// Multibyte UTF-8 character.
|
656
656
|
const char *prev = current;
|
657
|
-
|
658
|
-
|
659
|
-
|
657
|
+
try {
|
658
|
+
utf8::advance(current, 1, end);
|
659
|
+
result.append(prev, current - prev);
|
660
|
+
} catch (const utf8::invalid_utf8 &e) {
|
661
|
+
result.append("?"); // Oops, not UTF-8 after all, don't parse it.
|
662
|
+
current++;
|
663
|
+
}
|
660
664
|
} else {
|
661
665
|
// ASCII character <= 127.
|
662
666
|
if (ch == '<') {
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2010 Phusion Holding B.V.
|
3
|
+
* Copyright (c) 2010-2016 Phusion Holding B.V.
|
4
4
|
*
|
5
5
|
* "Passenger", "Phusion Passenger" and "Union Station" are registered
|
6
6
|
* trademarks of Phusion Holding B.V.
|
@@ -24,15 +24,26 @@
|
|
24
24
|
* THE SOFTWARE.
|
25
25
|
*/
|
26
26
|
|
27
|
-
#include <
|
27
|
+
#include <Utils/SystemTime.h>
|
28
28
|
|
29
29
|
namespace Passenger {
|
30
30
|
namespace SystemTimeData {
|
31
|
+
bool initialized = false;
|
31
32
|
bool hasForcedValue = false;
|
32
33
|
time_t forcedValue = 0;
|
33
|
-
bool hasForcedMsecValue = false;
|
34
|
-
unsigned long long forcedMsecValue = 0;
|
35
34
|
bool hasForcedUsecValue = false;
|
36
35
|
unsigned long long forcedUsecValue = 0;
|
36
|
+
|
37
|
+
#if BOOST_OS_MACOS
|
38
|
+
mach_timebase_info_data_t timeInfo;
|
39
|
+
#elif defined(SYSTEM_TIME_HAVE_MONOTONIC_CLOCK)
|
40
|
+
#ifdef SYSTEM_TIME_HAVE_CLOCK_MONOTONIC_COARSE
|
41
|
+
unsigned long long monotonicCoarseResolutionNs = 0;
|
42
|
+
#endif
|
43
|
+
#ifdef SYSTEM_TIME_HAVE_CLOCK_MONOTONIC_FAST
|
44
|
+
unsigned long long monotonicFastResolutionNs = 0;
|
45
|
+
#endif
|
46
|
+
unsigned long long monotonicResolutionNs;
|
47
|
+
#endif
|
37
48
|
}
|
38
49
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2010 Phusion Holding B.V.
|
3
|
+
* Copyright (c) 2010-2016 Phusion Holding B.V.
|
4
4
|
*
|
5
5
|
* "Passenger", "Phusion Passenger" and "Union Station" are registered
|
6
6
|
* trademarks of Phusion Holding B.V.
|
@@ -27,34 +27,221 @@
|
|
27
27
|
#define _PASSENGER_SYSTEM_TIME_H_
|
28
28
|
|
29
29
|
#include <boost/thread.hpp>
|
30
|
+
#include <boost/predef.h>
|
31
|
+
#include <oxt/macros.hpp>
|
30
32
|
#include <oxt/system_calls.hpp>
|
31
|
-
#include
|
33
|
+
#include <sys/time.h>
|
34
|
+
#include <cerrno>
|
35
|
+
#include <time.h>
|
36
|
+
#include <unistd.h>
|
37
|
+
#include <Exceptions.h>
|
38
|
+
|
39
|
+
#if BOOST_OS_MACOS
|
40
|
+
#include <mach/mach.h>
|
41
|
+
#include <mach/mach_time.h>
|
42
|
+
#include <cstring>
|
43
|
+
#elif BOOST_OS_AIX
|
44
|
+
#include <sys/systemcfg.h>
|
45
|
+
#elif defined(_POSIX_MONOTONIC_CLOCK) || defined(CLOCK_MONOTONIC)
|
46
|
+
#define SYSTEM_TIME_HAVE_MONOTONIC_CLOCK
|
47
|
+
#ifdef CLOCK_MONOTONIC_COARSE
|
48
|
+
#define SYSTEM_TIME_HAVE_CLOCK_MONOTONIC_COARSE
|
49
|
+
#endif
|
50
|
+
#ifdef CLOCK_MONOTONIC_FAST
|
51
|
+
#define SYSTEM_TIME_HAVE_CLOCK_MONOTONIC_FAST
|
52
|
+
#endif
|
53
|
+
#endif
|
32
54
|
|
33
55
|
namespace Passenger {
|
34
56
|
|
57
|
+
using namespace std;
|
35
58
|
using namespace oxt;
|
36
59
|
|
37
60
|
namespace SystemTimeData {
|
61
|
+
extern bool initialized;
|
38
62
|
extern bool hasForcedValue;
|
39
63
|
extern time_t forcedValue;
|
40
|
-
extern bool hasForcedMsecValue;
|
41
|
-
extern unsigned long long forcedMsecValue;
|
42
64
|
extern bool hasForcedUsecValue;
|
43
65
|
extern unsigned long long forcedUsecValue;
|
66
|
+
|
67
|
+
#if BOOST_OS_MACOS
|
68
|
+
extern mach_timebase_info_data_t timeInfo;
|
69
|
+
#elif defined(SYSTEM_TIME_HAVE_MONOTONIC_CLOCK)
|
70
|
+
#ifdef SYSTEM_TIME_HAVE_CLOCK_MONOTONIC_COARSE
|
71
|
+
extern unsigned long long monotonicCoarseResolutionNs;
|
72
|
+
#endif
|
73
|
+
#ifdef SYSTEM_TIME_HAVE_CLOCK_MONOTONIC_FAST
|
74
|
+
extern unsigned long long monotonicFastResolutionNs;
|
75
|
+
#endif
|
76
|
+
extern unsigned long long monotonicResolutionNs;
|
77
|
+
#endif
|
44
78
|
}
|
45
79
|
|
80
|
+
typedef unsigned long long MonotonicTimeUsec;
|
81
|
+
|
46
82
|
/**
|
47
83
|
* This class allows one to obtain the system time, similar to time() and
|
48
84
|
* gettimeofday(). Unlike time(), it is possible to force a certain time
|
49
85
|
* to be returned, which is useful for testing code that depends on the
|
50
86
|
* system time.
|
51
87
|
*
|
52
|
-
* get() provides seconds resolution while
|
88
|
+
* get() provides seconds resolution while getUsec() provides microseconds
|
53
89
|
* resolution. Both clocks can be independently forced to a certain value
|
54
|
-
* through force() and
|
90
|
+
* through force() and forceUsec().
|
91
|
+
*
|
92
|
+
* In addition, getMonotonicUsec() returns the monotonic clock in
|
93
|
+
* microseconds. This can also be forced to a certain value using forceUsec().
|
94
|
+
*
|
95
|
+
* Before using any SystemTime functions, you should call
|
96
|
+
* SystemTime::initialize(). If you don't do that, then initialize() will be
|
97
|
+
* called for you, but since initialize() isn't thread-safe you should
|
98
|
+
* call it at the beginning of your program.
|
55
99
|
*/
|
56
100
|
class SystemTime {
|
57
101
|
public:
|
102
|
+
enum Granularity {
|
103
|
+
GRAN_1SEC = 1000000000, // 1 millisecond granularity
|
104
|
+
GRAN_10MSEC = 10000000, // 10 milliseconds granularity
|
105
|
+
GRAN_1MSEC = 1000000, // 1 millisecond granularity
|
106
|
+
GRAN_1USEC = 1000 // 1 microsecond granularty
|
107
|
+
};
|
108
|
+
|
109
|
+
private:
|
110
|
+
static void initializeIfNeeded() {
|
111
|
+
if (OXT_UNLIKELY(!SystemTimeData::initialized)) {
|
112
|
+
initialize();
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
template<Granularity granularityNs>
|
117
|
+
static MonotonicTimeUsec _getMonotonicUsec() {
|
118
|
+
if (OXT_UNLIKELY(SystemTimeData::hasForcedUsecValue)) {
|
119
|
+
return SystemTimeData::hasForcedValue;
|
120
|
+
}
|
121
|
+
|
122
|
+
#if BOOST_OS_MACOS
|
123
|
+
initializeIfNeeded();
|
124
|
+
if (SystemTimeData::timeInfo.numer == 0
|
125
|
+
&& SystemTimeData::timeInfo.denom == 0)
|
126
|
+
{
|
127
|
+
return getUsec();
|
128
|
+
} else {
|
129
|
+
return mach_absolute_time()
|
130
|
+
* SystemTimeData::timeInfo.numer
|
131
|
+
/ SystemTimeData::timeInfo.denom
|
132
|
+
/ 1000;
|
133
|
+
}
|
134
|
+
|
135
|
+
#elif BOOST_OS_SOLARIS
|
136
|
+
return gethrtime() / 1000ull;
|
137
|
+
|
138
|
+
#elif BOOST_OS_AIX
|
139
|
+
timebasestruct_t t;
|
140
|
+
read_wall_time(&t, TIMEBASE_SZ);
|
141
|
+
time_base_to_time(&t, TIMEBASE_SZ);
|
142
|
+
return t.tb_high * 1000000ull + t.tb_low / 1000ull;
|
143
|
+
|
144
|
+
#elif defined(SYSTEM_TIME_HAVE_MONOTONIC_CLOCK)
|
145
|
+
clockid_t clockId = (clockid_t) -1;
|
146
|
+
struct timespec ts;
|
147
|
+
int ret;
|
148
|
+
|
149
|
+
initializeIfNeeded();
|
150
|
+
|
151
|
+
// We choose a different monotonic clock
|
152
|
+
// based on the resolution we need. In general,
|
153
|
+
// coarser resolutions are faster, for example
|
154
|
+
// because (on Linux) they are implemented
|
155
|
+
// through VDSOs instead of system calls.
|
156
|
+
//
|
157
|
+
// Benchmarks and properties as of 10 March 2016:
|
158
|
+
//
|
159
|
+
// FreeBSD 10.2 (200000 iterations):
|
160
|
+
// CLOCK_MONOTONIC 1m 9s 11 nanosec resolution
|
161
|
+
// CLOCK_MONOTONIC_PRECISE 1m 9s 11 nanosec resolution
|
162
|
+
// CLOCK_MONOTONIC_FAST 2s 11 nanosec resolution
|
163
|
+
// gettimeofday 1m 9s
|
164
|
+
//
|
165
|
+
// Linux 3.13.0 (100000000 iterations):
|
166
|
+
// CLOCK_MONOTONIC 1.5s 1 nanosec resolution
|
167
|
+
// CLOCK_MONOTONIC_COARSE 0.45s 4 millisec resolution
|
168
|
+
// gettimeofday 1.5s
|
169
|
+
|
170
|
+
#ifdef SYSTEM_TIME_HAVE_CLOCK_MONOTONIC_COARSE
|
171
|
+
if (clockId == -1
|
172
|
+
&& SystemTimeData::monotonicCoarseResolutionNs != 0
|
173
|
+
&& SystemTimeData::monotonicCoarseResolutionNs <= granularityNs)
|
174
|
+
{
|
175
|
+
clockId = CLOCK_MONOTONIC_COARSE;
|
176
|
+
}
|
177
|
+
#endif
|
178
|
+
#ifdef SYSTEM_TIME_HAVE_CLOCK_MONOTONIC_FAST
|
179
|
+
if (clockId == -1
|
180
|
+
&& SystemTimeData::monotonicFastResolutionNs != 0
|
181
|
+
&& SystemTimeData::monotonicFastResolutionNs <= granularityNs)
|
182
|
+
{
|
183
|
+
clockId = CLOCK_MONOTONIC_FAST;
|
184
|
+
}
|
185
|
+
#endif
|
186
|
+
if (clockId == -1
|
187
|
+
&& SystemTimeData::monotonicResolutionNs != 0
|
188
|
+
&& SystemTimeData::monotonicResolutionNs <= granularityNs)
|
189
|
+
{
|
190
|
+
clockId = CLOCK_MONOTONIC;
|
191
|
+
}
|
192
|
+
|
193
|
+
if (clockId == (clockid_t) -1) {
|
194
|
+
return getUsec();
|
195
|
+
} else {
|
196
|
+
do {
|
197
|
+
ret = clock_gettime(clockId, &ts);
|
198
|
+
} while (ret == -1 && errno == EINTR);
|
199
|
+
if (ret == -1) {
|
200
|
+
int e = errno;
|
201
|
+
throw TimeRetrievalException(
|
202
|
+
"Unable to retrieve the system time",
|
203
|
+
e);
|
204
|
+
}
|
205
|
+
return ts.tv_sec * 1000000ull + ts.tv_nsec / 1000ull;
|
206
|
+
}
|
207
|
+
|
208
|
+
#else
|
209
|
+
return getUsec();
|
210
|
+
#endif
|
211
|
+
}
|
212
|
+
|
213
|
+
public:
|
214
|
+
static void initialize() {
|
215
|
+
SystemTimeData::initialized = true;
|
216
|
+
#if BOOST_OS_MACOS
|
217
|
+
if (mach_timebase_info(&SystemTimeData::timeInfo) != KERN_SUCCESS) {
|
218
|
+
memset(&SystemTimeData::timeInfo, 0, sizeof(SystemTimeData::timeInfo));
|
219
|
+
}
|
220
|
+
#elif defined(SYSTEM_TIME_HAVE_MONOTONIC_CLOCK)
|
221
|
+
struct timespec ts;
|
222
|
+
|
223
|
+
#ifdef CLOCK_MONOTONIC_COARSE
|
224
|
+
if (clock_getres(CLOCK_MONOTONIC_COARSE, &ts) == 0) {
|
225
|
+
SystemTimeData::monotonicCoarseResolutionNs =
|
226
|
+
ts.tv_sec * 1000000000ull +
|
227
|
+
ts.tv_nsec;
|
228
|
+
}
|
229
|
+
#endif
|
230
|
+
#ifdef CLOCK_MONOTONIC_FAST
|
231
|
+
if (clock_getres(CLOCK_MONOTONIC_FAST, &ts) == 0) {
|
232
|
+
SystemTimeData::monotonicFastResolutionNs =
|
233
|
+
ts.tv_sec * 1000000000ull +
|
234
|
+
ts.tv_nsec;
|
235
|
+
}
|
236
|
+
#endif
|
237
|
+
if (clock_getres(CLOCK_MONOTONIC, &ts) == 0) {
|
238
|
+
SystemTimeData::monotonicResolutionNs =
|
239
|
+
ts.tv_sec * 1000000000ull +
|
240
|
+
ts.tv_nsec;
|
241
|
+
}
|
242
|
+
#endif
|
243
|
+
}
|
244
|
+
|
58
245
|
/**
|
59
246
|
* Returns the time since the Epoch, measured in seconds. Or, if a time
|
60
247
|
* was forced with force(), then the forced time is returned instead.
|
@@ -63,7 +250,7 @@ public:
|
|
63
250
|
* @throws boost::thread_interrupted
|
64
251
|
*/
|
65
252
|
static time_t get() {
|
66
|
-
if (SystemTimeData::hasForcedValue) {
|
253
|
+
if (OXT_UNLIKELY(SystemTimeData::hasForcedValue)) {
|
67
254
|
return SystemTimeData::forcedValue;
|
68
255
|
} else {
|
69
256
|
time_t ret = syscalls::time(NULL);
|
@@ -78,16 +265,15 @@ public:
|
|
78
265
|
}
|
79
266
|
|
80
267
|
/**
|
81
|
-
* Returns the time since the Epoch, measured in
|
82
|
-
* time was forced with
|
268
|
+
* Returns the time since the Epoch, measured in microseconds. Or, if a
|
269
|
+
* time was forced with forceUsec(), then the forced time is returned instead.
|
83
270
|
*
|
84
|
-
* @param real Whether to get the real time, even if a value was forced.
|
85
271
|
* @throws TimeRetrievalException Something went wrong while retrieving the time.
|
86
272
|
* @throws boost::thread_interrupted
|
87
273
|
*/
|
88
|
-
static unsigned long long
|
89
|
-
if (SystemTimeData::
|
90
|
-
return SystemTimeData::
|
274
|
+
static unsigned long long getUsec() {
|
275
|
+
if (OXT_UNLIKELY(SystemTimeData::hasForcedUsecValue)) {
|
276
|
+
return SystemTimeData::forcedUsecValue;
|
91
277
|
} else {
|
92
278
|
struct timeval t;
|
93
279
|
int ret;
|
@@ -101,35 +287,41 @@ public:
|
|
101
287
|
"Unable to retrieve the system time",
|
102
288
|
e);
|
103
289
|
}
|
104
|
-
return (unsigned long long) t.tv_sec *
|
290
|
+
return (unsigned long long) t.tv_sec * 1000000 + t.tv_usec;
|
105
291
|
}
|
106
292
|
}
|
107
293
|
|
108
294
|
/**
|
109
|
-
* Returns the time since
|
110
|
-
*
|
295
|
+
* Returns the time since an unspecified point in the last, measured in
|
296
|
+
* microseconds, using the monotonic clock.
|
297
|
+
*
|
298
|
+
* The monotonic clock is not subject to clock drift, even if the user
|
299
|
+
* changes the wall clock time. It is ideal for measuring time between
|
300
|
+
* two intervals.
|
301
|
+
*
|
302
|
+
* The returned time is guaranteed to have a granularity of 1 microsecond
|
303
|
+
* or better. In general, querying with coarser granularities is faster.
|
304
|
+
* If you want a coarser granularity, use `getMonotonicUsecWithGranularity()`
|
305
|
+
* instead.
|
306
|
+
*
|
307
|
+
* If the monotonic clock is not available (e.g. because the operating
|
308
|
+
* system doesn't support it), then this function returns the regular
|
309
|
+
* wall clock time instead (using `getUsec()`). If the monotonic clock
|
310
|
+
* is available, but an error occurred querying it, then a
|
311
|
+
* `TimeRetrievalException` is thrown.
|
312
|
+
*
|
313
|
+
* If the time was forced with forceUsed(), then the forced time is returned
|
314
|
+
* instead.
|
111
315
|
*
|
112
316
|
* @throws TimeRetrievalException Something went wrong while retrieving the time.
|
113
|
-
* @throws boost::thread_interrupted
|
114
317
|
*/
|
115
|
-
static
|
116
|
-
|
117
|
-
|
118
|
-
} else {
|
119
|
-
struct timeval t;
|
120
|
-
int ret;
|
318
|
+
static MonotonicTimeUsec getMonotonicUsec() {
|
319
|
+
return _getMonotonicUsec<GRAN_1USEC>();
|
320
|
+
}
|
121
321
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
if (ret == -1) {
|
126
|
-
int e = errno;
|
127
|
-
throw TimeRetrievalException(
|
128
|
-
"Unable to retrieve the system time",
|
129
|
-
e);
|
130
|
-
}
|
131
|
-
return (unsigned long long) t.tv_sec * 1000000 + t.tv_usec;
|
132
|
-
}
|
322
|
+
template<Granularity granularity>
|
323
|
+
static MonotonicTimeUsec getMonotonicUsecWithGranularity() {
|
324
|
+
return _getMonotonicUsec<granularity>();
|
133
325
|
}
|
134
326
|
|
135
327
|
/**
|
@@ -140,14 +332,6 @@ public:
|
|
140
332
|
SystemTimeData::forcedValue = value;
|
141
333
|
}
|
142
334
|
|
143
|
-
/**
|
144
|
-
* Force getMsec() to return the given value.
|
145
|
-
*/
|
146
|
-
static void forceMsec(unsigned long long value) {
|
147
|
-
SystemTimeData::hasForcedMsecValue = true;
|
148
|
-
SystemTimeData::forcedMsecValue = value;
|
149
|
-
}
|
150
|
-
|
151
335
|
/**
|
152
336
|
* Force getUsec() to return the given value.
|
153
337
|
*/
|
@@ -158,7 +342,6 @@ public:
|
|
158
342
|
|
159
343
|
static void forceAll(unsigned long long usec) {
|
160
344
|
force(usec / 1000000);
|
161
|
-
forceMsec(usec / 1000);
|
162
345
|
forceUsec(usec);
|
163
346
|
}
|
164
347
|
|
@@ -170,14 +353,6 @@ public:
|
|
170
353
|
SystemTimeData::hasForcedValue = false;
|
171
354
|
}
|
172
355
|
|
173
|
-
/**
|
174
|
-
* Release the previously forced msec value, so that getMsec()
|
175
|
-
* returns the system time once again.
|
176
|
-
*/
|
177
|
-
static void releaseMsec() {
|
178
|
-
SystemTimeData::hasForcedMsecValue = false;
|
179
|
-
}
|
180
|
-
|
181
356
|
/**
|
182
357
|
* Release the previously forced usec value, so that getUsec()
|
183
358
|
* returns the system time once again.
|
@@ -187,12 +362,11 @@ public:
|
|
187
362
|
}
|
188
363
|
|
189
364
|
/**
|
190
|
-
* Release all previously forced values, so that get()
|
191
|
-
*
|
365
|
+
* Release all previously forced values, so that get() and
|
366
|
+
* getUsec() return the system time once again.
|
192
367
|
*/
|
193
368
|
static void releaseAll() {
|
194
369
|
SystemTimeData::hasForcedValue = false;
|
195
|
-
SystemTimeData::hasForcedMsecValue = false;
|
196
370
|
SystemTimeData::hasForcedUsecValue = false;
|
197
371
|
}
|
198
372
|
};
|