最終更新:
library_task 2010年11月09日(火) 23:25:13履歴
accept()後に(たぶん・・・名前から推測)一回だけ通る関数。
ログに関する構造体の初期値設定を行う。
revのhandlerには、ngx_http_init_request
writeのhandlerにngx_http_empty_handlerをセット
205行目のif文(rev->ready) が真であればngx_http_init_request()と処理が続いていきます。
しかし、accept()した場合の段階ではrev->ready=0であり、このif文が真となりません。
rev->ready=1となる場所はこちら。
ngx_epoll_process_events()関数より。
ということで、いったんngx_http_init_connection()終了→ngx_event_accept()終了→ngx_epoll_process_events()と戻っていきます。
そしてぐるっと回って再びepoll_wait()
今度はaccept終わっているのでレベルトリガセットだったはず(未確認)
データが来ていればepoll_wait()を抜けて、rev->ready = 1が入るのです。
そして、ngx_epoll_process_events()のrev->handler(rev)→ngx_http_init_requestに飛ぶのでした。
では、ngx_http_init_requestでは何をするのでしょうか。
ngx_http_request_t構造体を作成、値をセットといったところですね。
Apacheにおけるrequest_r構造体と思われます。
さてrev->handler(rev);で飛ぶ先はどこかというと・・・ngx_http_process_request_line()のようですね。
SSLを使用している場合はngx_http_ssl_handshakeみたいですが、今はHTTPの処理を追いましょう。
ってことでngx_http_process_request_lineに行きます。
ログに関する構造体の初期値設定を行う。
revのhandlerには、ngx_http_init_request
writeのhandlerにngx_http_empty_handlerをセット
174 void 175 ngx_http_init_connection(ngx_connection_t *c) 176 { 177 ngx_event_t *rev; 178 ngx_http_log_ctx_t *ctx; 179 180 ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t)); 181 if (ctx == NULL) { 182 ngx_http_close_connection(c); 183 return; 184 } 185 186 ctx->connection = c; 187 ctx->request = NULL; 188 ctx->current_request = NULL; 189 190 c->log->connection = c->number; 191 c->log->handler = ngx_http_log_error; 192 c->log->data = ctx; 193 c->log->action = "reading client request line"; 194 195 c->log_error = NGX_ERROR_INFO; 196 197 rev = c->read; 198 rev->handler = ngx_http_init_request; 199 c->write->handler = ngx_http_empty_handler; 200 201 #if (NGX_STAT_STUB) 202 (void) ngx_atomic_fetch_add(ngx_stat_reading, 1); 203 #endif 204 205 if (rev->ready) { 206 /* the deferred accept(), rtsig, aio, iocp */ 207 208 if (ngx_use_accept_mutex) { 209 ngx_post_event(rev, &ngx_posted_events); 210 return; 211 } 212 213 ngx_http_init_request(rev); 214 return; 215 } 216 217 ngx_add_timer(rev, c->listening->post_accept_timeout); 218 219 if (ngx_handle_read_event(rev, 0) != NGX_OK) { 220 #if (NGX_STAT_STUB) 221 (void) ngx_atomic_fetch_add(ngx_stat_reading, -1); 222 #endif 223 ngx_http_close_connection(c); 224 return; 225 } 226 }
205行目のif文(rev->ready) が真であればngx_http_init_request()と処理が続いていきます。
しかし、accept()した場合の段階ではrev->ready=0であり、このif文が真となりません。
rev->ready=1となる場所はこちら。
ngx_epoll_process_events()関数より。
502 if ((revents & EPOLLIN) && rev->active) { 503 504 if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) { 505 rev->posted_ready = 1; 506 507 } else { 508 rev->ready = 1; 509 }
ということで、いったんngx_http_init_connection()終了→ngx_event_accept()終了→ngx_epoll_process_events()と戻っていきます。
そしてぐるっと回って再びepoll_wait()
今度はaccept終わっているのでレベルトリガセットだったはず(未確認)
データが来ていればepoll_wait()を抜けて、rev->ready = 1が入るのです。
そして、ngx_epoll_process_events()のrev->handler(rev)→ngx_http_init_requestに飛ぶのでした。
では、ngx_http_init_requestでは何をするのでしょうか。
229 static void 230 ngx_http_init_request(ngx_event_t *rev) 231 { 232 ngx_time_t *tp; 233 ngx_uint_t i; 234 ngx_connection_t *c; 235 ngx_http_request_t *r; 236 struct sockaddr_in *sin; 237 ngx_http_port_t *port; 238 ngx_http_in_addr_t *addr; 239 ngx_http_log_ctx_t *ctx; 240 ngx_http_addr_conf_t *addr_conf; 241 ngx_http_connection_t *hc; 242 ngx_http_core_srv_conf_t *cscf; 243 ngx_http_core_loc_conf_t *clcf; 244 ngx_http_core_main_conf_t *cmcf; 245 #if (NGX_HAVE_INET6) 246 struct sockaddr_in6 *sin6; 247 ngx_http_in6_addr_t *addr6; 248 #endif 249 250 #if (NGX_STAT_STUB) 251 (void) ngx_atomic_fetch_add(ngx_stat_reading, -1); 252 #endif 253 254 c = rev->data; 255 256 if (rev->timedout) { 257 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); 258 259 ngx_http_close_connection(c); 260 return; 261 } 262 263 c->requests++; 264 265 hc = c->data; 266 267 if (hc == NULL) { 268 hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t)); 269 if (hc == NULL) { 270 ngx_http_close_connection(c); 271 return; 272 } 273 } 274 275 r = hc->request; 276 277 if (r) { 278 ngx_memzero(r, sizeof(ngx_http_request_t)); 279 280 r->pipeline = hc->pipeline; 281 282 if (hc->nbusy) { 283 r->header_in = hc->busy[0]; 284 } 285 286 } else { 287 r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)); 288 if (r == NULL) { 289 ngx_http_close_connection(c); 290 return; 291 } 292 293 hc->request = r; 294 } 295 296 c->data = r; 297 r->http_connection = hc; 298 299 c->sent = 0; 300 r->signature = NGX_HTTP_MODULE; 301 302 /* find the server configuration for the address:port */ 303 304 port = c->listening->servers; 305 306 r->connection = c; 307 308 if (port->naddrs > 1) { 309 310 /* 311 * there are several addresses on this port and one of them 312 * is an "*:port" wildcard so getsockname() in ngx_http_server_addr() 313 * is required to determine a server address 314 */ 315 316 if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) { 317 ngx_http_close_connection(c); 318 return; 319 } 320 321 switch (c->local_sockaddr->sa_family) { 322 323 #if (NGX_HAVE_INET6) 324 case AF_INET6: 325 sin6 = (struct sockaddr_in6 *) c->local_sockaddr; 326 327 addr6 = port->addrs; 328 329 /* the last address is "*" */ 330 331 for (i = 0; i < port->naddrs - 1; i++) { 332 if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) { 333 break; 334 } 335 } 336 337 addr_conf = &addr6[i].conf; 338 339 break; 340 #endif 341 342 default: /* AF_INET */ 343 sin = (struct sockaddr_in *) c->local_sockaddr; 344 345 addr = port->addrs; 346 347 /* the last address is "*" */ 348 349 for (i = 0; i < port->naddrs - 1; i++) { 350 if (addr[i].addr == sin->sin_addr.s_addr) { 351 break; 352 } 353 } 354 355 addr_conf = &addr[i].conf; 356 357 break; 358 } 359 360 } else { 361 362 switch (c->local_sockaddr->sa_family) { 363 364 #if (NGX_HAVE_INET6) 365 case AF_INET6: 366 addr6 = port->addrs; 367 addr_conf = &addr6[0].conf; 368 break; 369 #endif 370 371 default: /* AF_INET */ 372 addr = port->addrs; 373 addr_conf = &addr[0].conf; 374 break; 375 } 376 } 377 378 r->virtual_names = addr_conf->virtual_names; 379 380 /* the default server configuration for the address:port */ 381 cscf = addr_conf->core_srv_conf; 382 383 r->main_conf = cscf->ctx->main_conf; 384 r->srv_conf = cscf->ctx->srv_conf; 385 r->loc_conf = cscf->ctx->loc_conf; 386 387 rev->handler = ngx_http_process_request_line; 388 r->read_event_handler = ngx_http_block_reading; 389 390 #if (NGX_HTTP_SSL) 391 392 { 393 ngx_http_ssl_srv_conf_t *sscf; 394 395 sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); 396 if (sscf->enable || addr_conf->ssl) { 397 398 if (c->ssl == NULL) { 399 400 c->log->action = "SSL handshaking"; 401 402 if (addr_conf->ssl && sscf->ssl.ctx == NULL) { 403 ngx_log_error(NGX_LOG_ERR, c->log, 0, 404 "no \"ssl_certificate\" is defined " 405 "in server listening on SSL port"); 406 ngx_http_close_connection(c); 407 return; 408 } 409 410 if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER) 411 != NGX_OK) 412 { 413 ngx_http_close_connection(c); 414 return; 415 } 416 417 rev->handler = ngx_http_ssl_handshake; 418 } 419 420 r->main_filter_need_in_memory = 1; 421 } 422 } 423 424 #endif 425 426 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 427 c->log->file = clcf->error_log->file; 428 if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { 429 c->log->log_level = clcf->error_log->log_level; 430 } 431 432 if (c->buffer == NULL) { 433 c->buffer = ngx_create_temp_buf(c->pool, 434 cscf->client_header_buffer_size); 435 if (c->buffer == NULL) { 436 ngx_http_close_connection(c); 437 return; 438 } 439 } 440 441 if (r->header_in == NULL) { 442 r->header_in = c->buffer; 443 } 444 445 r->pool = ngx_create_pool(cscf->request_pool_size, c->log); 446 if (r->pool == NULL) { 447 ngx_http_close_connection(c); 448 return; 449 } 450 451 452 if (ngx_list_init(&r->headers_out.headers, r->pool, 20, 453 sizeof(ngx_table_elt_t)) 454 != NGX_OK) 455 { 456 ngx_destroy_pool(r->pool); 457 ngx_http_close_connection(c); 458 return; 459 } 460 461 r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module); 462 if (r->ctx == NULL) { 463 ngx_destroy_pool(r->pool); 464 ngx_http_close_connection(c); 465 return; 466 } 467 468 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); 469 470 r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts 471 * sizeof(ngx_http_variable_value_t)); 472 if (r->variables == NULL) { 473 ngx_destroy_pool(r->pool); 474 ngx_http_close_connection(c); 475 return; 476 } 477 478 c->single_connection = 1; 479 c->destroyed = 0; 480 481 r->main = r; 482 483 tp = ngx_timeofday(); 484 r->start_sec = tp->sec; 485 r->start_msec = tp->msec; 486 487 r->method = NGX_HTTP_UNKNOWN; 488 489 r->headers_in.content_length_n = -1; 490 r->headers_in.keep_alive_n = -1; 491 r->headers_out.content_length_n = -1; 492 r->headers_out.last_modified_time = -1; 493 494 r->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1; 495 r->subrequests = NGX_HTTP_MAX_SUBREQUESTS + 1; 496 497 r->http_state = NGX_HTTP_READING_REQUEST_STATE; 498 499 ctx = c->log->data; 500 ctx->request = r; 501 ctx->current_request = r; 502 r->log_handler = ngx_http_log_error_handler; 503 504 #if (NGX_STAT_STUB) 505 (void) ngx_atomic_fetch_add(ngx_stat_reading, 1); 506 r->stat_reading = 1; 507 (void) ngx_atomic_fetch_add(ngx_stat_requests, 1); 508 #endif 509 510 rev->handler(rev); 511 }
ngx_http_request_t構造体を作成、値をセットといったところですね。
Apacheにおけるrequest_r構造体と思われます。
484 r->start_sec = tp->sec; 485 r->start_msec = tp->msec;を見ると、ログで処理時間を出すとした場合にここで取得した時刻との計算をするんだろうなと予想
さてrev->handler(rev);で飛ぶ先はどこかというと・・・ngx_http_process_request_line()のようですね。
SSLを使用している場合はngx_http_ssl_handshakeみたいですが、今はHTTPの処理を追いましょう。
ってことでngx_http_process_request_lineに行きます。
このページへのコメント
klAo0T <a href="http://dhfnuanrnlpm.com/">dhfnuanrnlpm</a>, [url=http://apchysdezpad.com/]apchysdezpad[/url], [link=http://arwgqpbmxmqi.com/]arwgqpbmxmqi[/link], http://tznyyylyssih.com/
lRVYqj <a href="http://ykfdcjkbgngh.com/">ykfdcjkbgngh</a>, [url=http://ajlougwsuplf.com/]ajlougwsuplf[/url], [link=http://mrfohjluvoze.com/]mrfohjluvoze[/link], http://trswhaaqowww.com/
lfOcqL <a href="http://mhimxbshcbvr.com/">mhimxbshcbvr</a>, [url=http://gcptyaaqnfvx.com/]gcptyaaqnfvx[/url], [link=http://gfgarjhcnyof.com/]gfgarjhcnyof[/link], http://sdjahycpglrq.com/