2014年10月27日月曜日

リクエスト処理の流れ: listener_thread(3) タイムアウト

(14.2) イベントチェック処理の続きだ。

(14.3) タイムアウト処理



ここで、スキップリストを処理する。
タイムアウトに至ったコールバック関数を実行している。

先にタイムアウトイベントまでの時間をチェックして、epollでは最大その時間を待つように
していた。
先のepoll_waitでタイムアウトが発生していれば、ここでタイムアウトの処理が実行されるはずだ。
もし、監視対象のソケットでイベントが発生していれば、タイムアウトより早く処理を終えているので、ここでのタイムアウト処理が行われない可能性がある。
しかし、既にタイムアウト時刻を過ぎて、timeout_intervalに1がセットされていた場合は、ここでタイムアウトが発生するだろう。

   1480         now = apr_time_now();
   1481         apr_thread_mutex_lock(g_timer_skiplist_mtx);
   1482         ep = apr_skiplist_peek(timer_skiplist);
   1483         while (ep) {
   1484             if (ep->when < now + EVENT_FUDGE_FACTOR) {

このif文では、スキップリストに登録されていたタイムアウト処理の実行時刻が、現在時刻(now)から
EVENT_FUDGE_FACTORまでの範囲に収まっているか、既に過ぎていた場合に、タイムアウト処理を開始する。

   1485                 apr_skiplist_pop(timer_skiplist, NULL);

スキップリストからタイムアウトイベント(ep)を取り出す。

   1486                 push_timer2worker(ep);

push_timer2worker()は、タイムアウトイベントepをworkerスレッドとの通信用のメッセージキューに登録している。
workerスレッド側ではこれをap_queue_pop_something()で取り出す。
ここで、タイムアウトイベントは、第5引数(timer_event_t **te)に渡される。

以下 workerスレッド内の該当の処理だ。

   1773         rv = ap_queue_pop_something(worker_queue, &csd, &cs, &ptrans, &te);
  :
   1803         if (te != NULL) {

この変数teにタイムアウトイベントがセットされる。
このif文にはタイムアウトイベントが渡されてきたときに入ることになる。

   1804             te->cbfunc(te->baton);
   1805

これが、そのタイムアウトイベントに登録されているコールバック関数の実行だ。

以下では、実行後に処理済みのタイムアウトイベントを再利用できるように、timer_free_ringに返している。

   1806             {
   1807                 apr_thread_mutex_lock(g_timer_skiplist_mtx);
   1808                 APR_RING_INSERT_TAIL(&timer_free_ring, te, timer_event_t, link);
   1809                 apr_thread_mutex_unlock(g_timer_skiplist_mtx);
   1810             }
   1811         }

   1487             }
   1488             else {
   1489                 break;
   1490             }
   1491             ep = apr_skiplist_peek(timer_skiplist);

そして、次のタイムアウトイベントをチェックする。
この1483行目からのwhile()ループで、タイムアウトしたタイムアウトイベントがworkerスレッドに全て渡されている。

   1492         }
   1493         apr_thread_mutex_unlock(g_timer_skiplist_mtx);
   1494

次は、イベント処理に進む。

0 件のコメント:

コメントを投稿