aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2015-08-27 09:43:09 +0000
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2015-08-27 09:43:09 +0000
commit70f7ad46ebc58f18599be8356751edda162ff435 (patch)
tree14f578c741051bb3b0ca660bd2e7e0903a086128 /src
parent0d2688a98bfc4f32b393fc581ec04e97d9b11449 (diff)
downloadlibmicrohttpd-70f7ad46ebc58f18599be8356751edda162ff435.tar.gz
libmicrohttpd-70f7ad46ebc58f18599be8356751edda162ff435.zip
Reimplement monotonic clock with wide range of platforms support
Diffstat (limited to 'src')
-rw-r--r--src/include/microhttpd.h2
-rw-r--r--src/microhttpd/Makefile.am1
-rw-r--r--src/microhttpd/connection.c5
-rw-r--r--src/microhttpd/connection_https.c5
-rw-r--r--src/microhttpd/daemon.c9
-rw-r--r--src/microhttpd/digestauth.c5
-rw-r--r--src/microhttpd/internal.c21
-rw-r--r--src/microhttpd/internal.h11
-rw-r--r--src/microhttpd/mhd_mono_clock.c312
-rw-r--r--src/microhttpd/mhd_mono_clock.h54
10 files changed, 383 insertions, 42 deletions
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 02939c1d..542c5f06 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -130,7 +130,7 @@ typedef intptr_t ssize_t;
130 * Current version of the library. 130 * Current version of the library.
131 * 0x01093001 = 1.9.30-1. 131 * 0x01093001 = 1.9.30-1.
132 */ 132 */
133#define MHD_VERSION 0x00094209 133#define MHD_VERSION 0x00094210
134 134
135/** 135/**
136 * MHD-internal return code for "YES". 136 * MHD-internal return code for "YES".
diff --git a/src/microhttpd/Makefile.am b/src/microhttpd/Makefile.am
index 020579d6..ecd949b2 100644
--- a/src/microhttpd/Makefile.am
+++ b/src/microhttpd/Makefile.am
@@ -62,6 +62,7 @@ libmicrohttpd_la_SOURCES = \
62 daemon.c \ 62 daemon.c \
63 internal.c internal.h \ 63 internal.c internal.h \
64 memorypool.c memorypool.h \ 64 memorypool.c memorypool.h \
65 mhd_mono_clock.c mhd_mono_clock.h \
65 mhd_limits.h mhd_byteorder.h \ 66 mhd_limits.h mhd_byteorder.h \
66 response.c response.h 67 response.c response.h
67libmicrohttpd_la_CPPFLAGS = \ 68libmicrohttpd_la_CPPFLAGS = \
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 06823edb..f1bd80bf 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -30,6 +30,7 @@
30#include "connection.h" 30#include "connection.h"
31#include "memorypool.h" 31#include "memorypool.h"
32#include "response.h" 32#include "response.h"
33#include "mhd_mono_clock.h"
33 34
34#if HAVE_NETINET_TCP_H 35#if HAVE_NETINET_TCP_H
35/* for TCP_CORK */ 36/* for TCP_CORK */
@@ -1970,7 +1971,7 @@ update_last_activity (struct MHD_Connection *connection)
1970{ 1971{
1971 struct MHD_Daemon *daemon = connection->daemon; 1972 struct MHD_Daemon *daemon = connection->daemon;
1972 1973
1973 connection->last_activity = MHD_monotonic_time(); 1974 connection->last_activity = MHD_monotonic_sec_counter();
1974 if (connection->connection_timeout != daemon->connection_timeout) 1975 if (connection->connection_timeout != daemon->connection_timeout)
1975 return; /* custom timeout, no need to move it in "normal" DLL */ 1976 return; /* custom timeout, no need to move it in "normal" DLL */
1976 1977
@@ -2656,7 +2657,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2656 } 2657 }
2657 timeout = connection->connection_timeout; 2658 timeout = connection->connection_timeout;
2658 if ( (0 != timeout) && 2659 if ( (0 != timeout) &&
2659 (timeout <= (MHD_monotonic_time() - connection->last_activity)) ) 2660 (timeout <= (MHD_monotonic_sec_counter() - connection->last_activity)) )
2660 { 2661 {
2661 MHD_connection_close (connection, 2662 MHD_connection_close (connection,
2662 MHD_REQUEST_TERMINATED_TIMEOUT_REACHED); 2663 MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
diff --git a/src/microhttpd/connection_https.c b/src/microhttpd/connection_https.c
index af359fac..433d2e43 100644
--- a/src/microhttpd/connection_https.c
+++ b/src/microhttpd/connection_https.c
@@ -30,6 +30,7 @@
30#include "connection.h" 30#include "connection.h"
31#include "memorypool.h" 31#include "memorypool.h"
32#include "response.h" 32#include "response.h"
33#include "mhd_mono_clock.h"
33#include <gnutls/gnutls.h> 34#include <gnutls/gnutls.h>
34 35
35 36
@@ -46,7 +47,7 @@ run_tls_handshake (struct MHD_Connection *connection)
46{ 47{
47 int ret; 48 int ret;
48 49
49 connection->last_activity = MHD_monotonic_time(); 50 connection->last_activity = MHD_monotonic_sec_counter();
50 if (connection->state == MHD_TLS_CONNECTION_INIT) 51 if (connection->state == MHD_TLS_CONNECTION_INIT)
51 { 52 {
52 ret = gnutls_handshake (connection->tls_session); 53 ret = gnutls_handshake (connection->tls_session);
@@ -139,7 +140,7 @@ MHD_tls_connection_handle_idle (struct MHD_Connection *connection)
139 MHD_state_to_string (connection->state)); 140 MHD_state_to_string (connection->state));
140#endif 141#endif
141 timeout = connection->connection_timeout; 142 timeout = connection->connection_timeout;
142 if ( (timeout != 0) && (timeout <= (MHD_monotonic_time() - connection->last_activity))) 143 if ( (timeout != 0) && (timeout <= (MHD_monotonic_sec_counter() - connection->last_activity)))
143 MHD_connection_close (connection, 144 MHD_connection_close (connection,
144 MHD_REQUEST_TERMINATED_TIMEOUT_REACHED); 145 MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
145 switch (connection->state) 146 switch (connection->state)
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index d8540abe..f516aefb 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -38,6 +38,7 @@
38#include "memorypool.h" 38#include "memorypool.h"
39#include "mhd_limits.h" 39#include "mhd_limits.h"
40#include "autoinit_funcs.h" 40#include "autoinit_funcs.h"
41#include "mhd_mono_clock.h"
41 42
42#if HAVE_SEARCH_H 43#if HAVE_SEARCH_H
43#include <search.h> 44#include <search.h>
@@ -822,7 +823,7 @@ MHD_handle_connection (void *data)
822#endif 823#endif
823 if (NULL == tvp && timeout > 0) 824 if (NULL == tvp && timeout > 0)
824 { 825 {
825 now = MHD_monotonic_time(); 826 now = MHD_monotonic_sec_counter();
826 if (now - con->last_activity > timeout) 827 if (now - con->last_activity > timeout)
827 tv.tv_sec = 0; 828 tv.tv_sec = 0;
828 else 829 else
@@ -1440,7 +1441,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
1440 connection->addr_len = addrlen; 1441 connection->addr_len = addrlen;
1441 connection->socket_fd = client_socket; 1442 connection->socket_fd = client_socket;
1442 connection->daemon = daemon; 1443 connection->daemon = daemon;
1443 connection->last_activity = MHD_monotonic_time(); 1444 connection->last_activity = MHD_monotonic_sec_counter();
1444 1445
1445 /* set default connection handlers */ 1446 /* set default connection handlers */
1446 MHD_set_http_callbacks_ (connection); 1447 MHD_set_http_callbacks_ (connection);
@@ -2175,7 +2176,7 @@ MHD_get_timeout (struct MHD_Daemon *daemon,
2175 2176
2176 if (MHD_NO == have_timeout) 2177 if (MHD_NO == have_timeout)
2177 return MHD_NO; 2178 return MHD_NO;
2178 now = MHD_monotonic_time(); 2179 now = MHD_monotonic_sec_counter();
2179 if (earliest_deadline < now) 2180 if (earliest_deadline < now)
2180 *timeout = 0; 2181 *timeout = 0;
2181 else 2182 else
@@ -4878,6 +4879,7 @@ void MHD_init(void)
4878#endif 4879#endif
4879 gnutls_global_init (); 4880 gnutls_global_init ();
4880#endif 4881#endif
4882 MHD_monotonic_sec_counter_init();
4881} 4883}
4882 4884
4883 4885
@@ -4890,6 +4892,7 @@ void MHD_fini(void)
4890 if (mhd_winsock_inited_) 4892 if (mhd_winsock_inited_)
4891 WSACleanup(); 4893 WSACleanup();
4892#endif 4894#endif
4895 MHD_monotonic_sec_counter_finish();
4893} 4896}
4894 4897
4895_SET_INIT_AND_DEINIT_FUNCS(MHD_init, MHD_fini); 4898_SET_INIT_AND_DEINIT_FUNCS(MHD_init, MHD_fini);
diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c
index e69f58aa..32ef79ef 100644
--- a/src/microhttpd/digestauth.c
+++ b/src/microhttpd/digestauth.c
@@ -26,6 +26,7 @@
26#include <limits.h> 26#include <limits.h>
27#include "internal.h" 27#include "internal.h"
28#include "md5.h" 28#include "md5.h"
29#include "mhd_mono_clock.h"
29 30
30#if defined(_WIN32) && defined(MHD_W32_MUTEX_) 31#if defined(_WIN32) && defined(MHD_W32_MUTEX_)
31#ifndef WIN32_LEAN_AND_MEAN 32#ifndef WIN32_LEAN_AND_MEAN
@@ -643,7 +644,7 @@ MHD_digest_auth_check (struct MHD_Connection *connection,
643 } 644 }
644 /* 8 = 4 hexadecimal numbers for the timestamp */ 645 /* 8 = 4 hexadecimal numbers for the timestamp */
645 nonce_time = strtoul (nonce + len - 8, (char **)NULL, 16); 646 nonce_time = strtoul (nonce + len - 8, (char **)NULL, 16);
646 t = (uint32_t) MHD_monotonic_time(); 647 t = (uint32_t) MHD_monotonic_sec_counter();
647 /* 648 /*
648 * First level vetting for the nonce validity: if the timestamp 649 * First level vetting for the nonce validity: if the timestamp
649 * attached to the nonce exceeds `nonce_timeout', then the nonce is 650 * attached to the nonce exceeds `nonce_timeout', then the nonce is
@@ -820,7 +821,7 @@ MHD_queue_auth_fail_response (struct MHD_Connection *connection,
820 char nonce[HASH_MD5_HEX_LEN + 9]; 821 char nonce[HASH_MD5_HEX_LEN + 9];
821 822
822 /* Generating the server nonce */ 823 /* Generating the server nonce */
823 calculate_nonce ((uint32_t) MHD_monotonic_time(), 824 calculate_nonce ((uint32_t) MHD_monotonic_sec_counter(),
824 connection->method, 825 connection->method,
825 connection->daemon->digest_auth_random, 826 connection->daemon->digest_auth_random,
826 connection->daemon->digest_auth_rand_size, 827 connection->daemon->digest_auth_rand_size,
diff --git a/src/microhttpd/internal.c b/src/microhttpd/internal.c
index 6a9188fd..b4f12521 100644
--- a/src/microhttpd/internal.c
+++ b/src/microhttpd/internal.c
@@ -171,25 +171,4 @@ MHD_http_unescape (char *val)
171} 171}
172 172
173 173
174/**
175 * Equivalent to time(NULL) but tries to use some sort of monotonic
176 * clock that isn't affected by someone setting the system real time
177 * clock.
178 *
179 * @return 'current' time
180 */
181time_t
182MHD_monotonic_time (void)
183{
184#ifdef HAVE_CLOCK_GETTIME
185#ifdef CLOCK_MONOTONIC
186 struct timespec ts;
187
188 if (0 == clock_gettime (CLOCK_MONOTONIC, &ts))
189 return ts.tv_sec;
190#endif
191#endif
192 return time (NULL);
193}
194
195/* end of internal.c */ 174/* end of internal.c */
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index fe487121..d2fdd925 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -1439,17 +1439,6 @@ struct MHD_Daemon
1439 1439
1440 1440
1441/** 1441/**
1442 * Equivalent to `time(NULL)` but tries to use some sort of monotonic
1443 * clock that isn't affected by someone setting the system real time
1444 * clock.
1445 *
1446 * @return 'current' time
1447 */
1448time_t
1449MHD_monotonic_time(void);
1450
1451
1452/**
1453 * Convert all occurences of '+' to ' '. 1442 * Convert all occurences of '+' to ' '.
1454 * 1443 *
1455 * @param arg string that is modified (in place), must be 0-terminated 1444 * @param arg string that is modified (in place), must be 0-terminated
diff --git a/src/microhttpd/mhd_mono_clock.c b/src/microhttpd/mhd_mono_clock.c
new file mode 100644
index 00000000..27591b46
--- /dev/null
+++ b/src/microhttpd/mhd_mono_clock.c
@@ -0,0 +1,312 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2015 Karlson2k (Evgeny Grin)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19
20/**
21 * @file microhttpd/mhd_mono_clock.h
22 * @brief internal monotonic clock functions implementations
23 * @author Karlson2k (Evgeny Grin)
24 */
25
26#include "mhd_mono_clock.h"
27
28#ifdef HAVE_CLOCK_GET_TIME
29#include <mach/mach.h>
30/* for host_get_clock_service(), mach_host_self(), mach_task_self() */
31#include <mach/clock.h>
32/* for clock_get_time() */
33
34#define _MHD_INVALID_CLOCK_SERV ((clock_serv_t) -2)
35
36static clock_serv_t mono_clock_service = _MHD_INVALID_CLOCK_SERV;
37#endif /* HAVE_CLOCK_GET_TIME */
38
39#ifdef HAVE_CLOCK_GETTIME
40#ifdef CLOCK_REALTIME
41#define _MHD_UNWANTED_CLOCK CLOCK_REALTIME
42#else /* !CLOCK_REALTIME */
43#define _MHD_UNWANTED_CLOCK ((clockid_t) -2)
44#endif /* !CLOCK_REALTIME */
45
46static clockid_t mono_clock_id = _MHD_UNWANTED_CLOCK;
47#endif /* HAVE_CLOCK_GETTIME */
48
49/* sync clocks; reduce chance of value wrap */
50static time_t mono_clock_start = 0;
51static time_t sys_clock_start = 0;
52#ifdef HAVE_GETHRTIME
53static hrtime_t hrtime_start = 0;
54#endif /* HAVE_GETHRTIME */
55#ifdef _WIN32
56#if _WIN32_WINNT >= 0x0600
57static uint64_t tick_start = 0;
58#else /* _WIN32_WINNT < 0x0600 */
59static int64_t perf_freq = 0;
60static int64_t perf_start = 0;
61#endif /* _WIN32_WINNT < 0x0600 */
62#endif /* _WIN32 */
63
64
65
66/**
67 * Type of monotonic clock source
68 */
69enum _MHD_mono_clock_source
70{
71 /**
72 * No monotonic clock
73 */
74 _MHD_CLOCK_NO_SOURCE = 0,
75
76 /**
77 * clock_gettime() with specific clock
78 */
79 _MHD_CLOCK_GETTIME,
80
81 /**
82 * clock_get_time() with specific clock service
83 */
84 _MHD_CLOCK_GET_TIME,
85
86 /**
87 * gethrtime() / 1000000000
88 */
89 _MHD_CLOCK_GETHRTIME,
90
91 /**
92 * GetTickCount64() / 1000
93 */
94 _MHD_CLOCK_GETTICKCOUNT64,
95
96 /**
97 * QueryPerformanceCounter() / QueryPerformanceFrequency()
98 */
99 _MHD_CLOCK_PERFCOUNTER
100};
101
102/**
103 * Initialise monotonic seconds counter.
104 */
105void
106MHD_monotonic_sec_counter_init (void)
107{
108#ifdef HAVE_CLOCK_GET_TIME
109 mach_timespec_t cur_time;
110#endif /* HAVE_CLOCK_GET_TIME */
111 enum _MHD_mono_clock_source mono_clock_source = _MHD_CLOCK_NO_SOURCE;
112#ifdef HAVE_CLOCK_GETTIME
113 struct timespec ts;
114
115 mono_clock_id = _MHD_UNWANTED_CLOCK;
116#endif /* HAVE_CLOCK_GETTIME */
117#ifdef HAVE_CLOCK_GET_TIME
118 mono_clock_service = _MHD_INVALID_CLOCK_SERV;
119#endif /* HAVE_CLOCK_GET_TIME */
120
121 if (0)
122 {
123 } else
124#ifdef HAVE_CLOCK_GETTIME
125#ifdef CLOCK_MONOTONIC_COARSE
126 /* Linux-specific fast value-getting clock */
127 /* Can be affected by frequency adjustment and don't count time in suspend, */
128 /* but preferred since it's fast */
129 if (0 == clock_gettime (CLOCK_MONOTONIC_COARSE, &ts))
130 {
131 mono_clock_id = CLOCK_MONOTONIC_COARSE;
132 mono_clock_start = ts.tv_sec;
133 mono_clock_source = _MHD_CLOCK_GETTIME;
134 } else
135#endif /* CLOCK_MONOTONIC_COARSE */
136#ifdef CLOCK_MONOTONIC_FAST
137 /* FreeBSD/DragonFly fast value-getting clock */
138 /* Can be affected by frequency adjustment, but preferred since it's fast */
139 if (0 == clock_gettime (CLOCK_MONOTONIC_FAST, &ts))
140 {
141 mono_clock_id = CLOCK_MONOTONIC_FAST;
142 mono_clock_start = ts.tv_sec;
143 mono_clock_source = _MHD_CLOCK_GETTIME;
144 } else
145#endif /* CLOCK_MONOTONIC_COARSE */
146#ifdef CLOCK_MONOTONIC_RAW
147 /* Linux-specific clock */
148 /* Not affected by frequency adjustment, but don't count time in suspend */
149 if (0 == clock_gettime (CLOCK_MONOTONIC_RAW , &ts))
150 {
151 mono_clock_id = CLOCK_MONOTONIC_RAW;
152 mono_clock_start = ts.tv_sec;
153 mono_clock_source = _MHD_CLOCK_GETTIME;
154 } else
155#endif /* CLOCK_MONOTONIC_RAW */
156#ifdef CLOCK_BOOTTIME
157 /* Linux-specific clock */
158 /* Count time in suspend so it's real monotonic on Linux, */
159 /* but can be slower value-getting than other clocks */
160 if (0 == clock_gettime(CLOCK_BOOTTIME, &ts))
161 {
162 mono_clock_id = CLOCK_BOOTTIME;
163 mono_clock_start = ts.tv_sec;
164 mono_clock_source = _MHD_CLOCK_GETTIME;
165 } else
166#endif /* CLOCK_BOOTTIME */
167#ifdef CLOCK_MONOTONIC
168 /* Monotonic clock */
169 /* Widely supported, may be affected by frequency adjustment */
170 /* On Linux it's not truly monotonic as it doesn't count time in suspend */
171 if (0 == clock_gettime(CLOCK_MONOTONIC, &ts))
172 {
173 mono_clock_id = CLOCK_MONOTONIC;
174 mono_clock_start = ts.tv_sec;
175 mono_clock_source = _MHD_CLOCK_GETTIME;
176 } else
177#endif /* CLOCK_BOOTTIME */
178#endif /* HAVE_CLOCK_GETTIME */
179#ifdef HAVE_CLOCK_GET_TIME
180 /* Darwin-specific monotonic clock */
181 /* Should be monotonic as clock_set_time function always unconditionally */
182 /* failed on latest kernels */
183 if (KERN_SUCCESS == host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &mono_clock_service) &&
184 KERN_SUCCESS == clock_get_time(mono_clock_service, &cur_time))
185 {
186 mono_clock_start = cur_time.tv_sec;
187 mono_clock_source = _MHD_CLOCK_GET_TIME;
188 } else
189#endif /* HAVE_CLOCK_GET_TIME */
190#ifdef _WIN32
191#if _WIN32_WINNT >= 0x0600
192 /* W32 Vista or later specific monotonic clock */
193 /* Available since Vista, ~15ms accuracy */
194 if (1)
195 {
196 tick_start = GetTickCount64();
197 mono_clock_source = _MHD_CLOCK_GETTICKCOUNT64;
198 } else
199#else /* _WIN32_WINNT < 0x0600 */
200 /* W32 specific monotonic clock */
201 /* Available on Windows 2000 and later */
202 if (1)
203 {
204 LARGE_INTEGER freq, perf_counter;
205 QueryPerformanceFrequency(&freq); /* never fail on XP and later */
206 QueryPerformanceCounter(&perf_counter); /* never fail on XP and later */
207 perf_freq = freq.QuadPart;
208 perf_start = perf_counter.QuadPart;
209 mono_clock_source = _MHD_CLOCK_PERFCOUNTER;
210 } else
211#endif /* _WIN32_WINNT < 0x0600 */
212#endif /* _WIN32 */
213#ifdef HAVE_CLOCK_GETTIME
214#ifdef CLOCK_HIGHRES
215 /* Solaris-specific monotonic high-resolution clock */
216 /* Not preferred due to be potentially resource-hungry */
217 if (0 == clock_gettime(CLOCK_HIGHRES, &ts))
218 {
219 mono_clock_id = CLOCK_HIGHRES;
220 mono_clock_start = ts.tv_sec;
221 mono_clock_source = _MHD_CLOCK_GETTIME;
222 } else
223#endif /* CLOCK_HIGHRES */
224#endif /* HAVE_CLOCK_GETTIME */
225#ifdef HAVE_GETHRTIME
226 /* HP-UX and Solaris monotonic clock */
227 /* Not preferred due to be potentially resource-hungry */
228 if (1)
229 {
230 hrtime_start = gethrtime();
231 mono_clock_source = _MHD_CLOCK_GETHRTIME;
232 } else
233#endif /* HAVE_GETHRTIME */
234 {
235 /* no suitable clock source was found */
236 mono_clock_source = _MHD_CLOCK_NO_SOURCE;
237 }
238
239#ifdef HAVE_CLOCK_GET_TIME
240 if (_MHD_CLOCK_GET_TIME != mono_clock_source &&
241 _MHD_INVALID_CLOCK_SERV != mono_clock_service)
242 {
243 /* clock service was initialised but clock_get_time failed */
244 mach_port_deallocate(mach_task_self(), mono_clock_service);
245 mono_clock_service = _MHD_INVALID_CLOCK_SERV;
246 }
247#endif /* HAVE_CLOCK_GET_TIME */
248
249 sys_clock_start = time(NULL);
250}
251
252
253/**
254 * Deinitialise monotonic seconds counter by freeing any allocated resources
255 */
256void
257MHD_monotonic_sec_counter_finish(void)
258{
259#ifdef HAVE_CLOCK_GET_TIME
260 if (_MHD_INVALID_CLOCK_SERV != mono_clock_service)
261 {
262 mach_port_deallocate(mach_task_self(), mono_clock_service);
263 mono_clock_service = _MHD_INVALID_CLOCK_SERV;
264 }
265#endif /* HAVE_CLOCK_GET_TIME */
266}
267
268/**
269 * Monotonic seconds counter, useful for timeout calculation.
270 * Tries to be not affected by manually setting the system real time
271 * clock or adjustments by NTP synchronization.
272 *
273 * @return number of seconds from some fixed moment
274 */
275time_t
276MHD_monotonic_sec_counter (void)
277{
278#ifdef HAVE_CLOCK_GETTIME
279 struct timespec ts;
280
281 if (_MHD_UNWANTED_CLOCK != mono_clock_id &&
282 0 == clock_gettime (mono_clock_id , &ts))
283 return ts.tv_sec - mono_clock_start;
284#endif /* HAVE_CLOCK_GETTIME */
285#ifdef HAVE_CLOCK_GET_TIME
286 if (_MHD_INVALID_CLOCK_SERV != mono_clock_service)
287 {
288 mach_timespec_t cur_time;
289 if (KERN_SUCCESS == clock_get_time(mono_clock_service, &cur_time))
290 return cur_time.tv_sec - mono_clock_start;
291 }
292#endif /* HAVE_CLOCK_GET_TIME */
293#if defined(_WIN32)
294#if _WIN32_WINNT >= 0x0600
295 if (1)
296 return (time_t)(((uint64_t)(GetTickCount64() - tick_start)) / 1000);
297#else /* _WIN32_WINNT < 0x0600 */
298 if (0 != perf_freq)
299 {
300 LARGE_INTEGER perf_counter;
301 QueryPerformanceCounter(&perf_counter); /* never fail on XP and later */
302 return (time_t)(((uint64_t)(perf_counter.QuadPart - perf_start)) / perf_freq);
303 }
304#endif /* _WIN32_WINNT < 0x0600 */
305#endif /* _WIN32 */
306#ifdef HAVE_GETHRTIME
307 if (1)
308 return (time_t)(((uint64_t)(gethrtime() - hrtime_start)) / 1000000000);
309#endif /* HAVE_GETHRTIME */
310
311 return time(NULL) - sys_clock_start;
312}
diff --git a/src/microhttpd/mhd_mono_clock.h b/src/microhttpd/mhd_mono_clock.h
new file mode 100644
index 00000000..2c515d63
--- /dev/null
+++ b/src/microhttpd/mhd_mono_clock.h
@@ -0,0 +1,54 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2015 Karlson2k (Evgeny Grin)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19
20/**
21 * @file microhttpd/mhd_mono_clock.h
22 * @brief internal monotonic clock functions declarations
23 * @author Karlson2k (Evgeny Grin)
24 */
25
26#ifndef MHD_MONO_CLOCK_H
27#define MHD_MONO_CLOCK_H 1
28#include "platform.h"
29
30/**
31 * Initialise monotonic seconds counter.
32 */
33void
34MHD_monotonic_sec_counter_init(void);
35
36
37/**
38 * Deinitialise monotonic seconds counter by freeing any allocated resources
39 */
40void
41MHD_monotonic_sec_counter_finish(void);
42
43
44/**
45 * Monotonic seconds counter, useful for timeout calculation.
46 * Tries to be not affected by manually setting the system real time
47 * clock or adjustments by NTP synchronization.
48 *
49 * @return number of seconds from some fixed moment
50 */
51time_t
52MHD_monotonic_sec_counter(void);
53
54#endif /* MHD_MONO_CLOCK_H */