Retry only for https protocol
[elinks.git] / src / util / time.c
blob5ef4b776ea6afd75a73641d55f6434bcd9a24508
1 /** Time operations
2 * @file */
4 #ifdef HAVE_CONFIG_H
5 #include "config.h"
6 #endif
8 #ifdef HAVE_SYS_TIME_H
9 #include <sys/time.h>
10 #endif
11 #ifdef HAVE_TIME_H
12 #include <time.h>
13 #endif
15 #include "elinks.h"
17 #include "osdep/osdep.h" /* For win32 gettimeofday() stub */
18 #include "util/error.h"
19 #include "util/time.h"
21 /** Get the current time.
22 * It attempts to use available functions, granularity
23 * may be as worse as 1 second if time() is used.
24 * @relates timeval_T */
25 timeval_T *
26 timeval_now(timeval_T *t)
28 #ifdef HAVE_GETTIMEOFDAY
29 struct timeval tv;
31 gettimeofday(&tv, NULL);
32 t->sec = (long) tv.tv_sec;
33 t->usec = (long) tv.tv_usec;
34 #else
35 #ifdef HAVE_CLOCK_GETTIME
36 struct timespec ts;
38 clock_gettime(CLOCK_REALTIME, &ts);
39 t->sec = (long) ts.tv_sec;
40 t->usec = (long) ts.tv_nsec / 1000;
41 #else
42 t->sec = (long) time(NULL);
43 t->usec = (long) 0;
44 #endif
45 #endif
47 return t;
50 /** Subtract an interval to a timeval, it ensures that
51 * result is never negative.
52 * @relates timeval_T */
53 timeval_T *
54 timeval_sub_interval(timeval_T *t, timeval_T *interval)
56 t->sec -= interval->sec;
57 if (t->sec < 0) {
58 t->sec = 0;
59 t->usec = 0;
60 return t;
63 t->usec -= interval->usec;
65 while (t->usec < 0) {
66 t->usec += 1000000;
67 t->sec--;
70 if (t->sec < 0) {
71 t->sec = 0;
72 t->usec = 0;
75 return t;
78 /** @relates timeval_T */
79 timeval_T *
80 timeval_sub(timeval_T *res, timeval_T *older, timeval_T *newer)
82 res->sec = newer->sec - older->sec;
83 res->usec = newer->usec - older->usec;
85 while (res->usec < 0) {
86 res->usec += 1000000;
87 res->sec--;
90 return res;
93 /** @relates timeval_T */
94 timeval_T *
95 timeval_add(timeval_T *res, timeval_T *base, timeval_T *t)
97 res->sec = base->sec + t->sec;
98 res->usec = base->usec + t->usec;
100 while (res->usec >= 1000000) {
101 res->usec -= 1000000;
102 res->sec++;
105 return res;
108 /** @relates timeval_T */
109 timeval_T *
110 timeval_add_interval(timeval_T *t, timeval_T *interval)
112 t->sec += interval->sec;
113 t->usec += interval->usec;
115 while (t->usec >= 1000000) {
116 t->usec -= 1000000;
117 t->sec++;
120 return t;
123 /** @relates timeval_T */
124 timeval_T *
125 timeval_from_double(timeval_T *t, double x)
127 t->sec = (long) x;
128 t->usec = (long) ((x - (double) t->sec) * 1000000);
130 return t;
133 /** @relates timeval_T */
134 timeval_T *
135 timeval_from_milliseconds(timeval_T *t, milliseconds_T milliseconds)
137 long ms = (long) milliseconds;
139 t->sec = ms / 1000;
140 t->usec = (ms % 1000) * 1000;
142 return t;
145 /** @bug 923: Assumes time_t values fit in long. (This function is used
146 * for both timestamps and durations.)
147 * @relates timeval_T */
148 timeval_T *
149 timeval_from_seconds(timeval_T *t, long seconds)
151 t->sec = seconds;
152 t->usec = 0;
154 return t;
157 milliseconds_T
158 sec_to_ms(long sec)
160 assert(sec >= 0 && sec < LONG_MAX / 1000L);
161 if_assert_failed return (milliseconds_T) (LONG_MAX / 1000L);
163 return (milliseconds_T) (sec * 1000L);
166 milliseconds_T
167 add_ms_to_ms(milliseconds_T a, milliseconds_T b)
169 long la = (long) a;
170 long lb = (long) b;
172 assert(la >= 0 && lb >= 0 && lb < LONG_MAX - la);
173 if_assert_failed return (milliseconds_T) (LONG_MAX / 1000L);
175 return (milliseconds_T) (la + lb);
178 milliseconds_T
179 mult_ms(milliseconds_T a, long lb)
181 long la = (long) a;
183 assert(la >= 0 && lb >= 0 && la < LONG_MAX / lb);
184 if_assert_failed return (milliseconds_T) (LONG_MAX / 1000L);
186 return (milliseconds_T) (la * lb);
189 /** @relates timeval_T */
190 milliseconds_T
191 timeval_to_milliseconds(timeval_T *t)
193 milliseconds_T a = sec_to_ms(t->sec);
194 milliseconds_T b = (milliseconds_T) (t->usec / 1000L);
196 return add_ms_to_ms(a, b);
199 /** @bug 923: Assumes time_t values fit in long. (This function is used
200 * for both timestamps and durations.)
201 * @relates timeval_T */
202 long
203 timeval_to_seconds(timeval_T *t)
205 return t->sec + t->usec / 1000000L;
208 /** @relates timeval_T */
210 timeval_is_positive(timeval_T *t)
212 return (t->sec > 0 || (t->sec == 0 && t->usec > 0));
215 /** Be sure timeval is not negative.
216 * @relates timeval_T */
217 void
218 timeval_limit_to_zero_or_one(timeval_T *t)
220 if (t->sec < 0) t->sec = 0;
221 if (t->usec < 0) t->usec = 0;
222 #ifdef CONFIG_OS_WIN32
223 /* Under Windows I got 300 seconds timeout, so 1 second should not hurt --witekfl */
224 if (t->sec > 1) t->sec = 1;
225 #endif
228 /** Compare time values.
229 * @returns 1 if t1 > t2;
230 * -1 if t1 < t2;
231 * 0 if t1 == t2.
232 * @relates timeval_T */
234 timeval_cmp(timeval_T *t1, timeval_T *t2)
236 if (t1->sec > t2->sec) return 1;
237 if (t1->sec < t2->sec) return -1;
239 return t1->usec - t2->usec;
242 /** @relates timeval_T */
244 timeval_div_off_t(off_t n, timeval_T *t)
246 longlong ln = 1000 * (longlong) n; /* FIXME: off_t -> longlong ??? Find a better way. --Zas */
247 longlong lsec = 1000 * (longlong) t->sec;
248 int lusec = t->usec / 1000;
250 if (lsec + lusec)
251 return (ln / (lsec + lusec));
252 else
253 return INT_MAX;