comparison ngx_http_upstream_keepalive_module.c @ 8:565939797f5c 0.1

Keepalive: fix connection closing and avoid for loop there. 1. Adding cache item to free queue was missed. 2. Loop over all cached connections isn't optimal, replace it with simple queue remove at cost of storing config pointer in each cache item.
author Maxim Dounin <mdounin@mdounin.ru>
date Fri, 24 Oct 2008 15:51:17 +0400
parents bef88ba0b378
children 06bd0e50e696
comparison
equal deleted inserted replaced
7:c1a2ef20a2a7 8:565939797f5c
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 #include <ngx_http.h> 9 #include <ngx_http.h>
10 10
11 11
12 typedef struct { 12 typedef struct {
13 ngx_uint_t max_cached;
14 ngx_uint_t single; /* unsigned:1 */
15
16 ngx_queue_t cache;
17 ngx_queue_t free;
18
19 ngx_http_upstream_init_pt original_init_upstream;
20 ngx_http_upstream_init_peer_pt original_init_peer;
21
22 } ngx_http_upstream_keepalive_srv_conf_t;
23
24
25 typedef struct {
26 ngx_http_upstream_keepalive_srv_conf_t *conf;
27
28 void *data;
29
30 ngx_event_get_peer_pt original_get_peer;
31 ngx_event_free_peer_pt original_free_peer;
32
33 } ngx_http_upstream_keepalive_peer_data_t;
34
35
36 typedef struct {
37 ngx_http_upstream_keepalive_srv_conf_t *conf;
38
13 ngx_queue_t queue; 39 ngx_queue_t queue;
14 ngx_connection_t *connection; 40 ngx_connection_t *connection;
15 41
16 socklen_t socklen; 42 socklen_t socklen;
17 struct sockaddr_storage sockaddr; 43 struct sockaddr_storage sockaddr;
18 44
19 } ngx_http_upstream_keepalive_cache_t; 45 } ngx_http_upstream_keepalive_cache_t;
20
21
22 typedef struct {
23 ngx_uint_t max_cached;
24 ngx_uint_t single; /* unsigned:1 */
25
26 ngx_queue_t cache;
27 ngx_queue_t free;
28
29 ngx_http_upstream_init_pt original_init_upstream;
30 ngx_http_upstream_init_peer_pt original_init_peer;
31
32 } ngx_http_upstream_keepalive_srv_conf_t;
33
34
35 typedef struct {
36 ngx_http_upstream_keepalive_srv_conf_t *conf;
37
38 void *data;
39
40 ngx_event_get_peer_pt original_get_peer;
41 ngx_event_free_peer_pt original_free_peer;
42
43 } ngx_http_upstream_keepalive_peer_data_t;
44 46
45 47
46 static ngx_int_t ngx_http_upstream_init_keepalive_peer(ngx_http_request_t *r, 48 static ngx_int_t ngx_http_upstream_init_keepalive_peer(ngx_http_request_t *r,
47 ngx_http_upstream_srv_conf_t *us); 49 ngx_http_upstream_srv_conf_t *us);
48 static ngx_int_t ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc, 50 static ngx_int_t ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc,
135 ngx_queue_init(&kcf->cache); 137 ngx_queue_init(&kcf->cache);
136 ngx_queue_init(&kcf->free); 138 ngx_queue_init(&kcf->free);
137 139
138 for (i = 0; i < kcf->max_cached; i++) { 140 for (i = 0; i < kcf->max_cached; i++) {
139 ngx_queue_insert_head(&kcf->free, &cached[i].queue); 141 ngx_queue_insert_head(&kcf->free, &cached[i].queue);
142 cached[i].conf = kcf;
140 } 143 }
141 144
142 return NGX_OK; 145 return NGX_OK;
143 } 146 }
144 147
303 } 306 }
304 307
305 c->write->handler = ngx_http_upstream_keepalive_dummy_handler; 308 c->write->handler = ngx_http_upstream_keepalive_dummy_handler;
306 c->read->handler = ngx_http_upstream_keepalive_close_handler; 309 c->read->handler = ngx_http_upstream_keepalive_close_handler;
307 310
308 c->data = kp->conf; 311 c->data = item;
309 c->idle = 1; 312 c->idle = 1;
310 c->log = ngx_cycle->log; 313 c->log = ngx_cycle->log;
311 c->read->log = ngx_cycle->log; 314 c->read->log = ngx_cycle->log;
312 c->write->log = ngx_cycle->log; 315 c->write->log = ngx_cycle->log;
313 316
331 ngx_http_upstream_keepalive_close_handler(ngx_event_t *ev) 334 ngx_http_upstream_keepalive_close_handler(ngx_event_t *ev)
332 { 335 {
333 ngx_http_upstream_keepalive_srv_conf_t *conf; 336 ngx_http_upstream_keepalive_srv_conf_t *conf;
334 ngx_http_upstream_keepalive_cache_t *item; 337 ngx_http_upstream_keepalive_cache_t *item;
335 338
336 ngx_queue_t *q, *cache;
337 ngx_connection_t *c; 339 ngx_connection_t *c;
338 340
339 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, 341 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0,
340 "keepalive close handler"); 342 "keepalive close handler");
341 343
342 c = ev->data; 344 c = ev->data;
343 conf = c->data; 345 item = c->data;
344 346 conf = item->conf;
345 cache = &conf->cache; 347
346 348 ngx_queue_remove(&item->queue);
347 for (q = ngx_queue_head(cache); 349 ngx_close_connection(item->connection);
348 q != ngx_queue_sentinel(cache); 350 ngx_queue_insert_head(&conf->free, &item->queue);
349 q = ngx_queue_next(q))
350 {
351 item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue);
352
353 if (item->connection == c) {
354 ngx_queue_remove(q);
355 ngx_close_connection(c);
356 return;
357 }
358 }
359
360 ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
361 "keepalive close handler: unknown connection %p", c);
362 ngx_close_connection(c);
363 } 351 }
364 352
365 353
366 static void * 354 static void *
367 ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf) 355 ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf)