blob: 6f6e5a4ff49b8c45a85470cf86da683ed683a45b [file] [log] [blame]
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00001
2#include <ngx_config.h>
Igor Sysoev0ad17c02002-08-26 15:18:19 +00003#include <ngx_core.h>
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00004#include <ngx_event.h>
Igor Sysoev7578ec92003-06-02 15:24:30 +00005#include <nginx.h>
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00006
7
Igor Sysoevd581fd52003-05-13 16:02:32 +00008void ngx_event_accept(ngx_event_t *ev)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00009{
Igor Sysoev6b863e32003-05-12 15:52:24 +000010 int instance;
Igor Sysoev86de4cb2003-01-30 07:28:09 +000011 socklen_t len;
12 struct sockaddr *sa;
Igor Sysoev42feecb2002-12-15 06:25:09 +000013 ngx_err_t err;
Igor Sysoev86de4cb2003-01-30 07:28:09 +000014 ngx_pool_t *pool;
Igor Sysoev42feecb2002-12-15 06:25:09 +000015 ngx_socket_t s;
16 ngx_event_t *rev, *wev;
Igor Sysoev86de4cb2003-01-30 07:28:09 +000017 ngx_connection_t *c, *ls;
Igor Sysoev13933252003-05-29 13:02:09 +000018 ngx_event_conf_t *ecf;
Igor Sysoev42feecb2002-12-15 06:25:09 +000019
Igor Sysoev13933252003-05-29 13:02:09 +000020 ecf = ngx_event_get_conf(ngx_event_module);
21
22 ls = ev->data;
Igor Sysoev86de4cb2003-01-30 07:28:09 +000023
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000024 ngx_log_debug(ev->log, "ngx_event_accept: accept ready: %d" _
25 ev->available);
Igor Sysoev86de4cb2003-01-30 07:28:09 +000026
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000027 ev->ready = 0;
Igor Sysoev86de4cb2003-01-30 07:28:09 +000028
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000029 do {
Igor Sysoev1c13c662003-05-20 15:37:55 +000030
Igor Sysoev7578ec92003-06-02 15:24:30 +000031 /*
32 * Create the pool before accept() to avoid copy the sockaddr.
33 * Although accept() can fail it's uncommon case
34 * and the pool can be got from the free pool list
35 */
Igor Sysoev1c13c662003-05-20 15:37:55 +000036
Igor Sysoevd581fd52003-05-13 16:02:32 +000037 pool = ngx_create_pool(ls->pool_size, ev->log);
38 if (pool == NULL) {
39 return;
40 }
Igor Sysoev86de4cb2003-01-30 07:28:09 +000041
Igor Sysoevd581fd52003-05-13 16:02:32 +000042 sa = ngx_palloc(pool, ls->socklen);
43 if (sa == NULL) {
44 return;
45 }
46
Igor Sysoev86de4cb2003-01-30 07:28:09 +000047 len = ls->socklen;
48
49 s = accept(ls->fd, sa, &len);
50 if (s == -1) {
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000051 err = ngx_socket_errno;
Igor Sysoev86de4cb2003-01-30 07:28:09 +000052
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000053 if (err == NGX_EAGAIN) {
Igor Sysoev86de4cb2003-01-30 07:28:09 +000054 ngx_log_error(NGX_LOG_NOTICE, ev->log, err,
Igor Sysoev13933252003-05-29 13:02:09 +000055 "EAGAIN while accept() %s", ls->addr_text.data);
Igor Sysoevd581fd52003-05-13 16:02:32 +000056 return;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000057 }
Igor Sysoev0ad17c02002-08-26 15:18:19 +000058
Igor Sysoev86de4cb2003-01-30 07:28:09 +000059 ngx_log_error(NGX_LOG_ALERT, ev->log, err,
Igor Sysoev13933252003-05-29 13:02:09 +000060 "accept() %s failed", ls->addr_text.data);
61
62 ngx_destroy_pool(pool);
63 return;
64 }
65
Igor Sysoevaa3436c2003-05-30 14:27:59 +000066 /* disable warnings: Win32 SOCKET is u_int while UNIX socket is int */
67 if ((unsigned) s >= (unsigned) ecf->connections) {
Igor Sysoev13933252003-05-29 13:02:09 +000068
69 ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
70 "accept() %s returned socket #%d while "
71 "only %d connections was configured, "
72 "sleeping for 1 second",
73 ls->addr_text.data, s, ecf->connections);
74
75 if (ngx_close_socket(s) == -1) {
76 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
77 ngx_close_socket_n " %s failed",
78 ls->addr_text.data);
79 }
80
Igor Sysoev1c104622003-06-03 15:42:58 +000081 ngx_msleep(1000);
Igor Sysoev13933252003-05-29 13:02:09 +000082
83 ngx_destroy_pool(pool);
Igor Sysoevd581fd52003-05-13 16:02:32 +000084 return;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000085 }
Igor Sysoev0ad17c02002-08-26 15:18:19 +000086
Igor Sysoevfa73aac2003-05-21 13:28:21 +000087 /* set a blocking mode for aio and non-blocking mode for others */
Igor Sysoev73009772003-02-06 17:21:13 +000088
Igor Sysoevfa73aac2003-05-21 13:28:21 +000089 if (ngx_inherited_nonblocking) {
90 if ((ngx_event_flags & NGX_USE_AIO_EVENT)) {
91 if (ngx_blocking(s) == -1) {
92 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
93 ngx_blocking_n " %s failed",
94 ls->addr_text.data);
Igor Sysoev13933252003-05-29 13:02:09 +000095
96 if (ngx_close_socket(s) == -1) {
97 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
98 ngx_close_socket_n " %s failed",
99 ls->addr_text.data);
100 }
101
102 ngx_destroy_pool(pool);
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000103 return;
104 }
105 }
Igor Sysoev73009772003-02-06 17:21:13 +0000106
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000107 } else {
108 if ((ngx_event_flags & NGX_USE_AIO_EVENT) == 0) {
109 if (ngx_nonblocking(s) == -1) {
110 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
111 ngx_nonblocking_n " %s failed",
112 ls->addr_text.data);
Igor Sysoev13933252003-05-29 13:02:09 +0000113
114 if (ngx_close_socket(s) == -1) {
115 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
116 ngx_close_socket_n " %s failed",
117 ls->addr_text.data);
118 }
119
120 ngx_destroy_pool(pool);
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000121 return;
122 }
Igor Sysoev73009772003-02-06 17:21:13 +0000123 }
124 }
Igor Sysoev73009772003-02-06 17:21:13 +0000125
Igor Sysoev42feecb2002-12-15 06:25:09 +0000126 rev = &ngx_read_events[s];
127 wev = &ngx_write_events[s];
128 c = &ngx_connections[s];
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000129
Igor Sysoev6b863e32003-05-12 15:52:24 +0000130 instance = rev->instance;
131
Igor Sysoev42feecb2002-12-15 06:25:09 +0000132 ngx_memzero(rev, sizeof(ngx_event_t));
133 ngx_memzero(wev, sizeof(ngx_event_t));
134 ngx_memzero(c, sizeof(ngx_connection_t));
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000135
Igor Sysoev86de4cb2003-01-30 07:28:09 +0000136 c->pool = pool;
137
138 c->sockaddr = sa;
139 c->family = ls->family;
140 c->socklen = len;
141 c->addr = ls->addr;
142 c->addr_text_max_len = ls->addr_text_max_len;
143 c->post_accept_timeout = ls->post_accept_timeout;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000144
Igor Sysoev6b863e32003-05-12 15:52:24 +0000145 rev->instance = wev->instance = !instance;
146
Igor Sysoev42feecb2002-12-15 06:25:09 +0000147 rev->index = wev->index = NGX_INVALID_INDEX;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000148
Igor Sysoev42feecb2002-12-15 06:25:09 +0000149 rev->data = wev->data = c;
150 c->read = rev;
151 c->write = wev;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000152
Igor Sysoev42feecb2002-12-15 06:25:09 +0000153 c->fd = s;
154 c->unexpected_eof = 1;
155 wev->write = 1;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000156
Igor Sysoev9e4920b2003-04-14 17:04:58 +0000157 if ((ngx_event_flags & NGX_USE_AIO_EVENT) == 0) {
Igor Sysoev73009772003-02-06 17:21:13 +0000158 wev->ready = 1;
159 }
Igor Sysoev73009772003-02-06 17:21:13 +0000160
Igor Sysoev86de4cb2003-01-30 07:28:09 +0000161 c->ctx = ls->ctx;
162 c->servers = ls->servers;
Igor Sysoev42feecb2002-12-15 06:25:09 +0000163
Igor Sysoevd581fd52003-05-13 16:02:32 +0000164 c->log = ngx_palloc(c->pool, sizeof(ngx_log_t));
165 if (c->log == NULL) {
166 return;
167 }
Igor Sysoev86de4cb2003-01-30 07:28:09 +0000168 ngx_memcpy(c->log, ev->log, sizeof(ngx_log_t));
169 rev->log = wev->log = c->log;
170
Igor Sysoev7578ec92003-06-02 15:24:30 +0000171 /* TODO: x86: MT: lock xadd, MP: lock xadd, shared */
Igor Sysoev42feecb2002-12-15 06:25:09 +0000172 c->number = ngx_connection_counter++;
173
Igor Sysoev13933252003-05-29 13:02:09 +0000174 ngx_log_debug(ev->log, "accept: %d, %d" _ s _ c->number);
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000175
Igor Sysoev13933252003-05-29 13:02:09 +0000176 if (ev->deferred_accept) {
Igor Sysoev42feecb2002-12-15 06:25:09 +0000177 rev->ready = 1;
Igor Sysoev86de4cb2003-01-30 07:28:09 +0000178 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000179
Igor Sysoev13933252003-05-29 13:02:09 +0000180 if (ngx_add_conn) {
181 if (ngx_add_conn(c) == NGX_ERROR) {
182 if (ngx_close_socket(s) == -1) {
183 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
184 ngx_close_socket_n " %s failed",
185 ls->addr_text.data);
186 }
Igor Sysoev6a644c62003-03-04 06:33:48 +0000187
Igor Sysoev13933252003-05-29 13:02:09 +0000188 ngx_destroy_pool(pool);
Igor Sysoevd581fd52003-05-13 16:02:32 +0000189 return;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000190 }
191 }
192
Igor Sysoev86de4cb2003-01-30 07:28:09 +0000193 ls->handler(c);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000194
Igor Sysoeva9830112003-05-19 16:39:14 +0000195 if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000196 ev->available--;
Igor Sysoev86de4cb2003-01-30 07:28:09 +0000197 }
198
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000199 } while (ev->available);
Igor Sysoev6253ca12003-05-27 12:18:54 +0000200
Igor Sysoevd581fd52003-05-13 16:02:32 +0000201 return;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000202}