comparison src/core/ngx_connection.c @ 635:e67b227c8dbb default tip

Merge with current.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 25 Apr 2011 04:07:55 +0400
parents b9763778e212
children
comparison
equal deleted inserted replaced
578:f3a9e57d2e17 635:e67b227c8dbb
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 #include <ngx_event.h> 9 #include <ngx_event.h>
10 10
11 11
12 ngx_os_io_t ngx_io; 12 ngx_os_io_t ngx_io;
13
14
15 static void ngx_drain_connections(void);
13 16
14 17
15 ngx_listening_t * 18 ngx_listening_t *
16 ngx_create_listening(ngx_conf_t *cf, void *sockaddr, socklen_t socklen) 19 ngx_create_listening(ngx_conf_t *cf, void *sockaddr, socklen_t socklen)
17 { 20 {
71 ls->type = SOCK_STREAM; 74 ls->type = SOCK_STREAM;
72 75
73 ls->backlog = NGX_LISTEN_BACKLOG; 76 ls->backlog = NGX_LISTEN_BACKLOG;
74 ls->rcvbuf = -1; 77 ls->rcvbuf = -1;
75 ls->sndbuf = -1; 78 ls->sndbuf = -1;
79
80 #if (NGX_HAVE_SETFIB)
81 ls->setfib = -1;
82 #endif
76 83
77 return ls; 84 return ls;
78 } 85 }
79 86
80 87
94 #endif 101 #endif
95 102
96 ls = cycle->listening.elts; 103 ls = cycle->listening.elts;
97 for (i = 0; i < cycle->listening.nelts; i++) { 104 for (i = 0; i < cycle->listening.nelts; i++) {
98 105
99 /* AF_INET only */ 106 ls[i].sockaddr = ngx_palloc(cycle->pool, NGX_SOCKADDRLEN);
100
101 ls[i].sockaddr = ngx_palloc(cycle->pool, sizeof(struct sockaddr_in));
102 if (ls[i].sockaddr == NULL) { 107 if (ls[i].sockaddr == NULL) {
103 return NGX_ERROR; 108 return NGX_ERROR;
104 } 109 }
105 110
106 ls[i].socklen = sizeof(struct sockaddr_in); 111 ls[i].socklen = NGX_SOCKADDRLEN;
107 if (getsockname(ls[i].fd, ls[i].sockaddr, &ls[i].socklen) == -1) { 112 if (getsockname(ls[i].fd, ls[i].sockaddr, &ls[i].socklen) == -1) {
108 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno, 113 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
109 "getsockname() of the inherited " 114 "getsockname() of the inherited "
110 "socket #%d failed", ls[i].fd); 115 "socket #%d failed", ls[i].fd);
111 ls[i].ignore = 1; 116 ls[i].ignore = 1;
178 "getsockopt(SO_SNDBUF) %V failed, ignored", 183 "getsockopt(SO_SNDBUF) %V failed, ignored",
179 &ls[i].addr_text); 184 &ls[i].addr_text);
180 185
181 ls[i].sndbuf = -1; 186 ls[i].sndbuf = -1;
182 } 187 }
188
189 #if 0
190 /* SO_SETFIB is currently a set only option */
191
192 #if (NGX_HAVE_SETFIB)
193
194 if (getsockopt(ls[i].setfib, SOL_SOCKET, SO_SETFIB,
195 (void *) &ls[i].setfib, &olen)
196 == -1)
197 {
198 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
199 "getsockopt(SO_SETFIB) %V failed, ignored",
200 &ls[i].addr_text);
201
202 ls[i].setfib = -1;
203 }
204
205 #endif
206 #endif
183 207
184 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) 208 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
185 209
186 ngx_memzero(&af, sizeof(struct accept_filter_arg)); 210 ngx_memzero(&af, sizeof(struct accept_filter_arg));
187 olen = sizeof(struct accept_filter_arg); 211 olen = sizeof(struct accept_filter_arg);
472 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, 496 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
473 "setsockopt(SO_SNDBUF, %d) %V failed, ignored", 497 "setsockopt(SO_SNDBUF, %d) %V failed, ignored",
474 ls[i].sndbuf, &ls[i].addr_text); 498 ls[i].sndbuf, &ls[i].addr_text);
475 } 499 }
476 } 500 }
501
502 #if (NGX_HAVE_SETFIB)
503 if (ls[i].setfib != -1) {
504 if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SETFIB,
505 (const void *) &ls[i].setfib, sizeof(int))
506 == -1)
507 {
508 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
509 "setsockopt(SO_SETFIB, %d) %V failed, ignored",
510 ls[i].setfib, &ls[i].addr_text);
511 }
512 }
513 #endif
477 514
478 #if 0 515 #if 0
479 if (1) { 516 if (1) {
480 int tcp_nodelay = 1; 517 int tcp_nodelay = 1;
481 518
683 /* ngx_mutex_lock */ 720 /* ngx_mutex_lock */
684 721
685 c = ngx_cycle->free_connections; 722 c = ngx_cycle->free_connections;
686 723
687 if (c == NULL) { 724 if (c == NULL) {
725 ngx_drain_connections();
726 c = ngx_cycle->free_connections;
727 }
728
729 if (c == NULL) {
688 ngx_log_error(NGX_LOG_ALERT, log, 0, 730 ngx_log_error(NGX_LOG_ALERT, log, 0,
689 "%ui worker_connections are not enough", 731 "%ui worker_connections are not enough",
690 ngx_cycle->connection_n); 732 ngx_cycle->connection_n);
691 733
692 /* ngx_mutex_unlock */ 734 /* ngx_mutex_unlock */
825 c->read->closed = 1; 867 c->read->closed = 1;
826 c->write->closed = 1; 868 c->write->closed = 1;
827 869
828 #endif 870 #endif
829 871
872 ngx_reusable_connection(c, 0);
873
830 log_error = c->log_error; 874 log_error = c->log_error;
831 875
832 ngx_free_connection(c); 876 ngx_free_connection(c);
833 877
834 fd = c->fd; 878 fd = c->fd;
860 904
861 /* we use ngx_cycle->log because c->log was in c->pool */ 905 /* we use ngx_cycle->log because c->log was in c->pool */
862 906
863 ngx_log_error(level, ngx_cycle->log, err, 907 ngx_log_error(level, ngx_cycle->log, err,
864 ngx_close_socket_n " %d failed", fd); 908 ngx_close_socket_n " %d failed", fd);
909 }
910 }
911
912
913 void
914 ngx_reusable_connection(ngx_connection_t *c, ngx_uint_t reusable)
915 {
916 ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
917 "reusable connection: %ui", reusable);
918
919 if (c->reusable) {
920 ngx_queue_remove(&c->queue);
921 }
922
923 c->reusable = reusable;
924
925 if (reusable) {
926 /* need cast as ngx_cycle is volatile */
927
928 ngx_queue_insert_head(
929 (ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue);
930 }
931 }
932
933
934 static void
935 ngx_drain_connections(void)
936 {
937 ngx_int_t i;
938 ngx_queue_t *q;
939 ngx_connection_t *c;
940
941 for (i = 0; i < 32; i++) {
942 if (ngx_queue_empty(&ngx_cycle->reusable_connections_queue)) {
943 break;
944 }
945
946 q = ngx_queue_last(&ngx_cycle->reusable_connections_queue);
947 c = ngx_queue_data(q, ngx_connection_t, queue);
948
949 ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
950 "reusing connection");
951
952 c->close = 1;
953 c->read->handler(c->read);
865 } 954 }
866 } 955 }
867 956
868 957
869 ngx_int_t 958 ngx_int_t