Mercurial > hg > nginx-vendor-1-0
comparison src/core/ngx_times.c @ 112:408f195b3482 NGINX_0_3_3
nginx 0.3.3
*) Change: the "bl" and "af" parameters of the "listen" directive was
renamed to the "backlog" and "accept_filter".
*) Feature: the "rcvbuf" and "sndbuf" parameters of the "listen"
directive.
*) Change: the "$msec" log parameter does not require now the
additional the gettimeofday() system call.
*) Feature: the -t switch now tests the "listen" directives.
*) Bugfix: if the invalid address was specified in the "listen"
directive, then after the -HUP signal nginx left an open socket in
the CLOSED state.
*) Bugfix: the mime type may be incorrectly set to default value for
index file with variable in the name; bug appeared in 0.3.0.
*) Feature: the "timer_resolution" directive.
*) Feature: the millisecond "$upstream_response_time" log parameter.
*) Bugfix: a temporary file with client request body now is removed
just after the response header was transferred to a client.
*) Bugfix: OpenSSL 0.9.6 compatibility.
*) Bugfix: the SSL certificate and key file paths could not be relative.
*) Bugfix: the "ssl_prefer_server_ciphers" directive did not work in
the ngx_imap_ssl_module.
*) Bugfix: the "ssl_protocols" directive allowed to specify the single
protocol only.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Wed, 19 Oct 2005 00:00:00 +0400 |
parents | 45f7329b4bd0 |
children | e0b1d0a6c629 |
comparison
equal
deleted
inserted
replaced
111:a175b609c76d | 112:408f195b3482 |
---|---|
6 | 6 |
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 | 9 |
10 | 10 |
11 ngx_msec_t ngx_current_time; | |
12 | |
13 ngx_int_t ngx_gmtoff; | |
14 | |
15 static ngx_tm_t ngx_cached_gmtime; | |
16 | |
17 | |
18 /* | 11 /* |
19 * In the threaded mode only one thread updates the cached time and strings | 12 * The time may be updated by signal handler or by several threads. |
20 * and these operations are protected by the mutex. The reading of the cached | 13 * The time update operations are rare and require to hold the ngx_time_lock. |
21 * time and strings is not protected by the mutex. To avoid the race | 14 * The time read operations are frequent, so they are lock-free and get time |
22 * conditions for non-atomic values we use the NGX_TIME_SLOTS slots to store | 15 * values and strings from the current slot. Thus thread may get the corrupted |
23 * time value and strings. Thus thread may get the corrupted values only | 16 * values only if it is preempted while copying and then it is not scheduled |
24 * if it is preempted while copying and then it is not scheduled to run | 17 * to run more than NGX_TIME_SLOTS seconds. |
25 * more than NGX_TIME_SLOTS seconds. | |
26 */ | 18 */ |
27 | 19 |
28 #if (NGX_THREADS) | 20 #define NGX_TIME_SLOTS 64 |
29 | 21 |
30 #define NGX_TIME_SLOTS 60 | 22 static ngx_uint_t slot = NGX_TIME_SLOTS; |
31 static ngx_uint_t slot = NGX_TIME_SLOTS; | 23 static ngx_atomic_t ngx_time_lock; |
32 | 24 |
33 static ngx_mutex_t *ngx_time_mutex; | 25 volatile ngx_msec_t ngx_current_msec; |
34 | 26 volatile ngx_time_t *ngx_cached_time; |
35 #else | 27 volatile ngx_str_t ngx_cached_err_log_time; |
36 | 28 volatile ngx_str_t ngx_cached_http_time; |
37 #define NGX_TIME_SLOTS 1 | 29 volatile ngx_str_t ngx_cached_http_log_time; |
38 #define slot 0 | 30 |
39 | 31 static ngx_time_t cached_time[NGX_TIME_SLOTS]; |
40 #endif | 32 static u_char cached_err_log_time[NGX_TIME_SLOTS] |
41 | 33 [sizeof("1970/09/28 12:00:00")]; |
42 | 34 static u_char cached_http_time[NGX_TIME_SLOTS] |
43 #if (NGX_THREADS && (NGX_TIME_T_SIZE > NGX_SIG_ATOMIC_T_SIZE)) | 35 [sizeof("Mon, 28 Sep 1970 06:00:00 GMT")]; |
44 | 36 static u_char cached_http_log_time[NGX_TIME_SLOTS] |
45 volatile time_t *ngx_cached_time; | 37 [sizeof("28/Sep/1970:12:00:00 +0600")]; |
46 static time_t cached_time[NGX_TIME_SLOTS]; | |
47 | |
48 #else | |
49 | |
50 volatile time_t ngx_cached_time; | |
51 | |
52 #endif | |
53 | |
54 | |
55 ngx_thread_volatile ngx_str_t ngx_cached_err_log_time; | |
56 ngx_thread_volatile ngx_str_t ngx_cached_http_time; | |
57 ngx_thread_volatile ngx_str_t ngx_cached_http_log_time; | |
58 | |
59 | |
60 static u_char cached_err_log_time[NGX_TIME_SLOTS] | |
61 [sizeof("1970/09/28 12:00:00")]; | |
62 static u_char cached_http_time[NGX_TIME_SLOTS] | |
63 [sizeof("Mon, 28 Sep 1970 06:00:00 GMT")]; | |
64 static u_char cached_http_log_time[NGX_TIME_SLOTS] | |
65 [sizeof("28/Sep/1970:12:00:00 +0600")]; | |
66 | 38 |
67 | 39 |
68 static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; | 40 static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; |
69 static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", | 41 static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", |
70 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; | 42 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; |
71 | 43 |
72 void | 44 void |
73 ngx_time_init(void) | 45 ngx_time_init(void) |
74 { | 46 { |
75 struct timeval tv; | |
76 | |
77 ngx_memzero(&ngx_cached_gmtime, sizeof(ngx_tm_t)); | |
78 #ifdef ngx_tm_zone | |
79 ngx_cached_gmtime.ngx_tm_zone = "GMT"; | |
80 #endif | |
81 | |
82 ngx_cached_err_log_time.len = sizeof("1970/09/28 12:00:00") - 1; | 47 ngx_cached_err_log_time.len = sizeof("1970/09/28 12:00:00") - 1; |
83 ngx_cached_http_time.len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1; | 48 ngx_cached_http_time.len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1; |
84 ngx_cached_http_log_time.len = sizeof("28/Sep/1970:12:00:00 +0600") - 1; | 49 ngx_cached_http_log_time.len = sizeof("28/Sep/1970:12:00:00 +0600") - 1; |
85 | 50 |
86 #if (NGX_THREADS && (NGX_TIME_T_SIZE > NGX_SIG_ATOMIC_T_SIZE)) | |
87 ngx_cached_time = &cached_time[0]; | 51 ngx_cached_time = &cached_time[0]; |
88 #endif | |
89 | |
90 ngx_gettimeofday(&tv); | |
91 | |
92 ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000; | |
93 | 52 |
94 #if !(NGX_WIN32) | 53 #if !(NGX_WIN32) |
95 tzset(); | 54 tzset(); |
96 #endif | 55 #endif |
97 | 56 |
98 ngx_time_update(tv.tv_sec); | 57 ngx_time_update(0, 0); |
99 } | 58 } |
100 | |
101 | |
102 #if (NGX_THREADS) | |
103 | |
104 ngx_int_t | |
105 ngx_time_mutex_init(ngx_log_t *log) | |
106 { | |
107 ngx_time_mutex = ngx_mutex_init(log, NGX_MUTEX_LIGHT); | |
108 | |
109 if (ngx_time_mutex == NULL) { | |
110 return NGX_ERROR; | |
111 } | |
112 | |
113 return NGX_OK; | |
114 } | |
115 | |
116 #endif | |
117 | 59 |
118 | 60 |
119 void | 61 void |
120 ngx_time_update(time_t s) | 62 ngx_time_update(time_t sec, ngx_uint_t msec) |
121 { | 63 { |
122 u_char *p; | 64 u_char *p0, *p1, *p2; |
123 ngx_tm_t tm; | 65 ngx_tm_t tm, gmt; |
124 | 66 ngx_time_t *tp; |
125 if (ngx_time() == s) { | 67 struct timeval tv; |
126 return; | 68 |
127 } | 69 if (!ngx_trylock(&ngx_time_lock)) { |
128 | |
129 #if (NGX_THREADS) | |
130 | |
131 if (ngx_mutex_trylock(ngx_time_mutex) != NGX_OK) { | |
132 return; | 70 return; |
133 } | 71 } |
134 | 72 |
135 if (slot == NGX_TIME_SLOTS) { | 73 if (slot == NGX_TIME_SLOTS) { |
136 slot = 0; | 74 slot = 0; |
137 } else { | 75 } else { |
138 slot++; | 76 slot++; |
139 } | 77 } |
140 | 78 |
141 #if (NGX_THREADS && (NGX_TIME_T_SIZE > NGX_SIG_ATOMIC_T_SIZE)) | 79 if (sec == 0) { |
142 ngx_cached_time = &cached_time[slot]; | 80 ngx_gettimeofday(&tv); |
81 | |
82 sec = tv.tv_sec; | |
83 msec = tv.tv_usec / 1000; | |
84 } | |
85 | |
86 ngx_current_msec = (ngx_msec_t) sec * 1000 + msec; | |
87 | |
88 tp = &cached_time[slot]; | |
89 | |
90 tp->msec = msec; | |
91 | |
92 if (tp->sec == sec) { | |
93 ngx_unlock(&ngx_time_lock); | |
94 return; | |
95 } | |
96 | |
97 tp->sec = sec; | |
98 | |
99 ngx_gmtime(sec, &gmt); | |
100 | |
101 | |
102 p0 = cached_http_time[slot]; | |
103 | |
104 (void) ngx_sprintf(p0, "%s, %02d %s %4d %02d:%02d:%02d GMT", | |
105 week[gmt.ngx_tm_wday], gmt.ngx_tm_mday, | |
106 months[gmt.ngx_tm_mon - 1], gmt.ngx_tm_year, | |
107 gmt.ngx_tm_hour, gmt.ngx_tm_min, gmt.ngx_tm_sec); | |
108 | |
109 #if (NGX_HAVE_GETTIMEZONE) | |
110 | |
111 tp->gmtoff = ngx_gettimezone(); | |
112 ngx_gmtime(sec + tp->gmtoff * 60, &tm); | |
113 | |
114 #elif (NGX_HAVE_GMTOFF) | |
115 | |
116 ngx_localtime(sec, &tm); | |
117 tp->gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60); | |
118 | |
119 #else | |
120 | |
121 ngx_localtime(sec, &tm); | |
122 tp->gmtoff = ngx_timezone(tm.ngx_tm_isdst); | |
123 | |
143 #endif | 124 #endif |
144 | 125 |
145 #endif | 126 |
146 | 127 p1 = cached_err_log_time[slot]; |
147 ngx_time() = s; | 128 |
148 | 129 (void) ngx_sprintf(p1, "%4d/%02d/%02d %02d:%02d:%02d", |
149 ngx_gmtime(s, &ngx_cached_gmtime); | |
150 | |
151 | |
152 p = cached_http_time[slot]; | |
153 | |
154 (void) ngx_sprintf(p, "%s, %02d %s %4d %02d:%02d:%02d GMT", | |
155 week[ngx_cached_gmtime.ngx_tm_wday], | |
156 ngx_cached_gmtime.ngx_tm_mday, | |
157 months[ngx_cached_gmtime.ngx_tm_mon - 1], | |
158 ngx_cached_gmtime.ngx_tm_year, | |
159 ngx_cached_gmtime.ngx_tm_hour, | |
160 ngx_cached_gmtime.ngx_tm_min, | |
161 ngx_cached_gmtime.ngx_tm_sec); | |
162 | |
163 ngx_cached_http_time.data = p; | |
164 | |
165 | |
166 #if (NGX_HAVE_GETTIMEZONE) | |
167 | |
168 ngx_gmtoff = ngx_gettimezone(); | |
169 ngx_gmtime(s + ngx_gmtoff * 60, &tm); | |
170 | |
171 #elif (NGX_HAVE_GMTOFF) | |
172 | |
173 ngx_localtime(&tm); | |
174 ngx_gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60); | |
175 | |
176 #else | |
177 | |
178 ngx_localtime(&tm); | |
179 ngx_gmtoff = ngx_timezone(tm.ngx_tm_isdst); | |
180 | |
181 #endif | |
182 | |
183 | |
184 p = cached_err_log_time[slot]; | |
185 | |
186 (void) ngx_sprintf(p, "%4d/%02d/%02d %02d:%02d:%02d", | |
187 tm.ngx_tm_year, tm.ngx_tm_mon, | 130 tm.ngx_tm_year, tm.ngx_tm_mon, |
188 tm.ngx_tm_mday, tm.ngx_tm_hour, | 131 tm.ngx_tm_mday, tm.ngx_tm_hour, |
189 tm.ngx_tm_min, tm.ngx_tm_sec); | 132 tm.ngx_tm_min, tm.ngx_tm_sec); |
190 | 133 |
191 ngx_cached_err_log_time.data = p; | 134 |
192 | 135 p2 = cached_http_log_time[slot]; |
193 | 136 |
194 p = cached_http_log_time[slot]; | 137 (void) ngx_sprintf(p2, "%02d/%s/%d:%02d:%02d:%02d %c%02d%02d", |
195 | |
196 (void) ngx_sprintf(p, "%02d/%s/%d:%02d:%02d:%02d %c%02d%02d", | |
197 tm.ngx_tm_mday, months[tm.ngx_tm_mon - 1], | 138 tm.ngx_tm_mday, months[tm.ngx_tm_mon - 1], |
198 tm.ngx_tm_year, tm.ngx_tm_hour, | 139 tm.ngx_tm_year, tm.ngx_tm_hour, |
199 tm.ngx_tm_min, tm.ngx_tm_sec, | 140 tm.ngx_tm_min, tm.ngx_tm_sec, |
200 ngx_gmtoff < 0 ? '-' : '+', | 141 tp->gmtoff < 0 ? '-' : '+', |
201 abs(ngx_gmtoff / 60), abs(ngx_gmtoff % 60)); | 142 ngx_abs(tp->gmtoff / 60), ngx_abs(tp->gmtoff % 60)); |
202 | 143 |
203 ngx_cached_http_log_time.data = p; | 144 |
204 | 145 ngx_memory_barrier(); |
205 | 146 |
206 #if (NGX_THREADS) | 147 ngx_cached_time = tp; |
207 ngx_mutex_unlock(ngx_time_mutex); | 148 ngx_cached_http_time.data = p0; |
208 #endif | 149 ngx_cached_err_log_time.data = p1; |
209 | 150 ngx_cached_http_log_time.data = p2; |
151 | |
152 ngx_unlock(&ngx_time_lock); | |
210 } | 153 } |
211 | 154 |
212 | 155 |
213 u_char * | 156 u_char * |
214 ngx_http_time(u_char *buf, time_t t) | 157 ngx_http_time(u_char *buf, time_t t) |