この辺、投稿としてまとめておく。
内容がダブってしまうが、事前に考えていないということだな。
内容がダブってしまうが、事前に考えていないということだな。
(1) KeepAlive接続の場合
接続済みのソケットにKeep-Aliveでリクエストが届くと、そのときに空きworkerスレッドが獲得できなければ、ソケットはクローズされる
(httpd-2.4.7/server/mpm/event/event.c)
1368 static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy)
1369 {
:
1414 for (;;) {
:
1495 while (num) {
1496 pt = (listener_poll_type *) out_pfd->client_data;
1497 if (pt->type == PT_CSD) {
1498 /* one of the sockets is readable */
:
1502 switch (cs->pub.state) {
1503 case CONN_STATE_CHECK_REQUEST_LINE_READABLE:
1504 cs->pub.state = CONN_STATE_READ_REQUEST_LINE;
1505 remove_from_q = &keepalive_q;
1506 /* don't wait for a worker for a keepalive request */
1507 blocking = 0;
1508 /* FALL THROUGH */
1509 case CONN_STATE_WRITE_COMPLETION:
1510 get_worker(&have_idle_worker, blocking,
1511 &workers_were_busy);
:
1532 /* If we didn't get a worker immediately for a keep-alive
1533 * request, we close the connection, so that the client can
1534 * re-connect to a different process.
1535 */
1536 if (!have_idle_worker) {
1537 start_lingering_close_nonblocking(cs);
1538 break;
1539 }
:
1510行目のget_worker()で利用可能なworkerスレッドが得られない場合(have_idle_workerが0)に、
1537行目でソケットを閉じている。
1532行目のコメントにもあるように、keep-aliveなリクエストに対してworkerスレッドが確保できなければ、直ちに接続を切り、クライアント側が再接続するのを待つという仕様になっている。
(2) 新規接続の場合
この場合、accept可能になった時点で、空きworkerスレッドが確保できなければ、accept自体を行わない。
(httpd-2.4.7/server/mpm/event/event.c) 1615 get_worker(&have_idle_worker, 1, &workers_were_busy); 1616 rc = lr->accept_func(&csd, lr, ptrans);
1615行目で、get_worker()は空きworkerスレッドが獲得できるまでブロックする。
そして、獲得後に、1616行目の関数からaccept()が実行される。
もし、別の子プロセスがいて、空きworkerスレッドがいたなら、そちらが先にaccept することになる。
この場合、空きworkerスレッドを待っていた子プロセスで、空きworkerスレッドが確保できて、1615行目から抜けたときの処理は、event MPMではソケットが非ブロックになっているので、1616行目の関数から呼び出されるaccept()処理が失敗する。
その後、確保したプールを解放するなどの処理を行ってから、何事もなく listenerスレッドとして監視処理を継続することになる。
0 件のコメント:
コメントを投稿