2014年3月27日木曜日

event MPM: listenerスレッドのリクエスト受付時の処理のメモ

前の投稿に書いたように、接続済みのソケットにKeep-Aliveでリクエストが届くと、そのときに空きworkerスレッドが獲得できなければ、ソケットはクローズされていた。
この辺、投稿としてまとめておく。
内容がダブってしまうが、事前に考えていないということだな。

(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 件のコメント:

コメントを投稿