comparison src/http/ngx_http_busy_lock.c @ 176:c0552e5ab567

nginx-0.0.1-2003-11-09-23:03:38 import; separate building
author Igor Sysoev <igor@sysoev.ru>
date Sun, 09 Nov 2003 20:03:38 +0000
parents e92c2c647c57
children a8ff48d26cca
comparison
equal deleted inserted replaced
175:e92c2c647c57 176:c0552e5ab567
2 #include <ngx_config.h> 2 #include <ngx_config.h>
3 #include <ngx_core.h> 3 #include <ngx_core.h>
4 #include <ngx_http.h> 4 #include <ngx_http.h>
5 5
6 6
7 int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, u_char *md5) 7
8 { 8 static int ngx_http_busy_lock_look_cachable(ngx_http_busy_lock_t *bl,
9 int i, b, busy, free; 9 ngx_http_busy_lock_ctx_t *bc,
10 int lock);
11
12
13 int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, ngx_http_busy_lock_ctx_t *bc)
14 {
15 if (bl->busy < bl->max_busy) {
16 bl->busy++;
17
18 if (bc->time) {
19 bc->time = 0;
20 bl->waiting--;
21 }
22
23 return NGX_OK;
24 }
25
26 if (bc->time) {
27 if (bc->time < bl->timeout) {
28 ngx_add_timer(bc->event, 1000);
29 return NGX_AGAIN;
30 }
31
32 bl->waiting--;
33 return NGX_DONE;
34
35 }
36
37 if (bl->timeout == 0) {
38 return NGX_DONE;
39 }
40
41 if (bl->waiting < bl->max_waiting) {
42 bl->waiting++;
43 ngx_add_timer(bc->event, 1000);
44 bc->event->event_handler = bc->event_handler;
45
46 /* TODO: ngx_handle_level_read_event() */
47
48 return NGX_AGAIN;
49 }
50
51 return NGX_ERROR;
52 }
53
54
55 int ngx_http_busy_lock_cachable(ngx_http_busy_lock_t *bl,
56 ngx_http_busy_lock_ctx_t *bc, int lock)
57 {
58 int rc;
59
60 rc = ngx_http_busy_lock_look_cachable(bl, bc, lock);
61
62 ngx_log_debug(bc->event->log, "BUSYLOCK: %d" _ rc);
63
64 if (rc == NGX_OK) { /* no the same request, there's free slot */
65 return NGX_OK;
66 }
67
68 if (rc == NGX_ERROR && !lock) { /* no the same request, no free slot */
69 return NGX_OK;
70 }
71
72 /* rc == NGX_AGAIN: the same request */
73
74 if (bc->time) {
75 if (bc->time < bl->timeout) {
76 ngx_add_timer(bc->event, 1000);
77 return NGX_AGAIN;
78 }
79
80 bl->waiting--;
81 return NGX_DONE;
82
83 }
84
85 if (bl->timeout == 0) {
86 return NGX_DONE;
87 }
88
89 if (bl->waiting < bl->max_waiting) {
90 bl->waiting++;
91 ngx_add_timer(bc->event, 1000);
92 bc->event->event_handler = bc->event_handler;
93
94 /* TODO: ngx_handle_level_read_event() */
95
96 return NGX_AGAIN;
97 }
98
99 return NGX_ERROR;
100 }
101
102
103 void ngx_http_busy_unlock_cachable(ngx_http_busy_lock_t *bl,
104 ngx_http_busy_lock_ctx_t *bc)
105 {
106 bl->md5_mask[bc->slot / 8] &= ~(1 << (bc->slot & 7));
107 bl->cachable--;
108 bl->busy--;
109 }
110
111
112 static int ngx_http_busy_lock_look_cachable(ngx_http_busy_lock_t *bl,
113 ngx_http_busy_lock_ctx_t *bc,
114 int lock)
115 {
116 int i, b, cachable, free;
10 u_int mask; 117 u_int mask;
11 118
12 b = 0; 119 b = 0;
13 busy = 0; 120 cachable = 0;
14 free = -1; 121 free = -1;
15 122
16 #if (NGX_SUPPRESS_WARN) 123 #if (NGX_SUPPRESS_WARN)
17 mask = 0; 124 mask = 0;
18 #endif 125 #endif
19 126
20 for (i = 0; i < bl->max_conn; i++) { 127 for (i = 0; i < bl->max_busy; i++) {
21 128
22 if ((b & 7) == 0) { 129 if ((b & 7) == 0) {
23 mask = bl->busy_mask[i / 8]; 130 mask = bl->md5_mask[i / 8];
24 } 131 }
25 132
26 if (mask & 1) { 133 if (mask & 1) {
27 if (ngx_memcmp(&bl->busy[i * 16], md5, 16) == 0) { 134 if (ngx_memcmp(&bl->md5[i * 16], bc->md5, 16) == 0) {
28 return NGX_AGAIN; 135 return NGX_AGAIN;
29 } 136 }
30 busy++; 137 cachable++;
31 138
32 } else if (free == -1) { 139 } else if (free == -1) {
33 free = i; 140 free = i;
34 } 141 }
35 142
36 if (busy == bl->busy_n) { 143 #if 1
37 if (busy < bl->max_conn) { 144 if (cachable == bl->cachable) {
145 if (free == -1 && cachable < bl->max_busy) {
38 free = i + 1; 146 free = i + 1;
39 } 147 }
40 148
41 break; 149 break;
42 } 150 }
151 #endif
43 152
44 mask >>= 1; 153 mask >>= 1;
45 b++; 154 b++;
46 } 155 }
47 156
48 if (free == -1) { 157 if (free == -1) {
49 return NGX_ERROR; 158 return NGX_ERROR;
50 } 159 }
51 160
52 ngx_memcpy(&bl->busy[free * 16], md5, 16); 161 if (lock) {
53 bl->busy_mask[free / 8] |= free % 8; 162 if (bl->busy == bl->max_busy) {
54 163 return NGX_ERROR;
55 bl->busy_n++; 164 }
56 bl->conn_n++; 165
166 ngx_memcpy(&bl->md5[free * 16], bc->md5, 16);
167 bl->md5_mask[free / 8] |= 1 << (free & 7);
168 bc->slot = free;
169
170 bl->cachable++;
171 bl->busy++;
172 }
57 173
58 return NGX_OK; 174 return NGX_OK;
59 } 175 }
60 176
61 177
62 char *ngx_http_set_busy_lock_slot(ngx_conf_t *cf, ngx_command_t *cmd, 178 char *ngx_http_set_busy_lock_slot(ngx_conf_t *cf, ngx_command_t *cmd,
63 void *conf) 179 void *conf)
64 { 180 {
65 char *p = conf; 181 char *p = conf;
66 182
67 int i; 183 int i, dup, invalid;
68 ngx_str_t *value; 184 ngx_str_t *value, line;
69 ngx_http_busy_lock_t *bl, **blp; 185 ngx_http_busy_lock_t *bl, **blp;
70 186
71 blp = (ngx_http_busy_lock_t **) (p + cmd->offset); 187 blp = (ngx_http_busy_lock_t **) (p + cmd->offset);
72 if (*blp) { 188 if (*blp) {
73 return "is duplicate"; 189 return "is duplicate";
77 if (!(bl = ngx_pcalloc(cf->pool, sizeof(ngx_http_busy_lock_t)))) { 193 if (!(bl = ngx_pcalloc(cf->pool, sizeof(ngx_http_busy_lock_t)))) {
78 return NGX_CONF_ERROR; 194 return NGX_CONF_ERROR;
79 } 195 }
80 *blp = bl; 196 *blp = bl;
81 197
198 dup = 0;
199 invalid = 0;
82 value = (ngx_str_t *) cf->args->elts; 200 value = (ngx_str_t *) cf->args->elts;
83 201
84 for (i = 1; i < 4; i++) { 202 for (i = 1; i < cf->args->nelts; i++) {
85 203
86 if (value[i].len > 2 && ngx_strncasecmp(value[i].data, "c:", 2) == 0) { 204 if (value[i].data[1] != '=') {
87 if (bl->max_conn) { 205 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
88 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 206 "invalid value \"%s\"", value[i].data);
89 "duplicate \"%s\"", value[i].data); 207 return NGX_CONF_ERROR;
90 return NGX_CONF_ERROR; 208 }
91 } 209
92 210 switch (value[i].data[0]) {
93 bl->max_conn = ngx_atoi(value[i].data + 2, value[i].len - 2); 211
94 if (bl->max_conn == NGX_ERROR) { 212 case 'b':
95 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 213 if (bl->max_busy) {
96 "invalid value \"%s\"", value[i].data); 214 dup = 1;
97 return NGX_CONF_ERROR; 215 break;
216 }
217
218 bl->max_busy = ngx_atoi(value[i].data + 2, value[i].len - 2);
219 if (bl->max_busy == NGX_ERROR) {
220 invalid = 1;
221 break;
98 } 222 }
99 223
100 continue; 224 continue;
101 } 225
102 226 case 'w':
103 if (value[i].len > 2 && ngx_strncasecmp(value[i].data, "w:", 2) == 0) {
104 if (bl->max_waiting) { 227 if (bl->max_waiting) {
105 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 228 dup = 1;
106 "duplicate \"%s\"", value[i].data); 229 break;
107 return NGX_CONF_ERROR;
108 } 230 }
109 231
110 bl->max_waiting = ngx_atoi(value[i].data + 2, value[i].len - 2); 232 bl->max_waiting = ngx_atoi(value[i].data + 2, value[i].len - 2);
111 if (bl->max_waiting == NGX_ERROR) { 233 if (bl->max_waiting == NGX_ERROR) {
112 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 234 invalid = 1;
235 break;
236 }
237
238 continue;
239
240 case 't':
241 if (bl->timeout) {
242 dup = 1;
243 break;
244 }
245
246 line.len = value[i].len - 2;
247 line.data = value[i].data + 2;
248
249 bl->timeout = ngx_parse_time(&line, 1);
250 if (bl->timeout == NGX_ERROR) {
251 invalid = 1;
252 break;
253 }
254
255 continue;
256
257 default:
258 invalid = 1;
259 }
260
261 if (dup) {
262 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
263 "duplicate value \"%s\"", value[i].data);
264 return NGX_CONF_ERROR;
265 }
266
267 if (invalid) {
268 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
113 "invalid value \"%s\"", value[i].data); 269 "invalid value \"%s\"", value[i].data);
114 return NGX_CONF_ERROR;
115 }
116
117 continue;
118 }
119
120 if (bl->timeout) {
121 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
122 "duplicate timeout \"%s\"", value[i].data);
123 return NGX_CONF_ERROR; 270 return NGX_CONF_ERROR;
124 } 271 }
125 272 }
126 bl->timeout = ngx_parse_time(&value[1], 1); 273
127 if (bl->timeout == NGX_ERROR) { 274 if (bl->timeout == 0 && bl->max_waiting) {
128 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 275 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
129 "invalid timeout \"%s\"", value[i].data); 276 "busy lock waiting is useless with zero timeout");
130 return NGX_CONF_ERROR;
131 }
132 } 277 }
133 278
134 return NGX_CONF_OK; 279 return NGX_CONF_OK;
135 } 280 }