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)