# 機能設計書 3-イベントループ実行

## 概要

本ドキュメントは、libuvライブラリにおけるイベントループ実行機能（`uv_run()`）の設計仕様を記述する。`uv_run()`はイベントループの中核であり、登録されたハンドルやリクエストの処理を駆動するメインループである。

### 本機能の処理概要

`uv_run()`は、イベントループを指定されたモード（DEFAULT/ONCE/NOWAIT）で実行する関数である。タイマー処理、保留中のコールバック実行、I/Oポーリング、チェックコールバック、クローズ処理など、イベントループの1イテレーションに含まれる全てのフェーズを順序立てて実行する。

**業務上の目的・背景**：非同期I/Oプログラミングの中核として、登録された全てのイベントハンドラを適切なタイミングで呼び出す。ネットワークサーバー、ファイル監視、タイマー処理など、あらゆる非同期処理はこの関数を通じて駆動される。

**機能の利用シーン**：
- サーバーアプリケーションのメインループとして`UV_RUN_DEFAULT`で使用
- GUIアプリケーション等で他のイベントループと統合する際に`UV_RUN_NOWAIT`で使用
- 1回のイベント処理のみ行いたい場合に`UV_RUN_ONCE`で使用

**主要な処理内容**：
1. ループの生存確認（アクティブなハンドル/リクエストの有無チェック）
2. 内部時刻キャッシュの更新とタイマー処理
3. 保留中コールバックの実行
4. アイドルハンドルの実行
5. プリペアハンドルの実行
6. I/Oポーリング（タイムアウト計算付き）
7. メトリクスの更新
8. チェックハンドルの実行
9. クロージングハンドルの処理
10. ループモードに応じた継続/終了判定

**関連システム・外部連携**：プラットフォーム固有のI/Oイベント通知機構（kqueue/epoll/IOCP）を`uv__io_poll()`を通じて使用する。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | 設計概要 | 主機能 | イベントループの設計思想とイテレーション図を用いた動作原理の解説 |
| 6 | イベントループ | 主機能 | uv_run()によるイベントループ実行のAPI定義 |
| 33 | 基本事項 | 主機能 | uv_run()によるイベントループ実行の実践的な使い方の解説 |
| 38 | イベントループ応用 | 主機能 | NOWAITモードでのループ実行の使用例 |
| 42 | 0.10→1.0.0マイグレーション | 補助機能 | uv_run()のセマンティクス変更の説明 |

## 機能種別

イベント駆動処理 / メインループ制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| loop | uv_loop_t* | Yes | 実行対象のイベントループ | NULLチェックなし |
| mode | uv_run_mode | Yes | 実行モード（UV_RUN_DEFAULT=0, UV_RUN_ONCE=1, UV_RUN_NOWAIT=2） | 暗黙的（enumの範囲外は未定義） |

### 入力データソース

呼び出し元が`uv_loop_init()`または`uv_default_loop()`で初期化済みのイベントループ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | ループにアクティブなハンドル/リクエストが残っている場合は非0、ない場合は0 |

### 出力先

関数の戻り値、およびイベントループに登録された各コールバックの呼び出し。

## 処理フロー

### 処理シーケンス

```
1. ループ生存確認
   └─ uv__loop_alive(loop)でアクティブハンドル/リクエスト/保留中キュー/クロージング中ハンドルを確認
2. 時刻更新（ループが生存していない場合）
   └─ uv__update_time(loop)
3. DEFAULTモード時の初回タイマー処理
   └─ uv__update_time() + uv__run_timers()
4. メインループ開始（r != 0 && stop_flag == 0の間継続）
   a. スリープ可能判定
      └─ pending_queueとidle_handlesが空かチェック
   b. 保留中コールバック実行
      └─ uv__run_pending(loop)
   c. アイドルハンドル実行
      └─ uv__run_idle(loop)
   d. プリペアハンドル実行
      └─ uv__run_prepare(loop)
   e. I/Oポーリングタイムアウト計算
      └─ DEFAULT/ONCEモードでcan_sleepの場合はuv__backend_timeout()、それ以外は0
   f. メトリクスカウント増加
      └─ uv__metrics_inc_loop_count(loop)
   g. I/Oポーリング実行
      └─ uv__io_poll(loop, timeout)
   h. 追加の保留中コールバック実行（最大8回）
      └─ ループスターベーション防止
   i. メトリクスアイドル時間更新
      └─ uv__metrics_update_idle_time(loop)
   j. チェックハンドル実行
      └─ uv__run_check(loop)
   k. クロージングハンドル処理
      └─ uv__run_closing_handles(loop)
   l. 時刻更新とタイマー処理
      └─ uv__update_time(loop) + uv__run_timers(loop)
   m. ループ生存確認と継続判定
      └─ ONCE/NOWAITモードならbreak
5. stop_flagのリセット
   └─ 条件付きで0にリセット（キャッシュライン汚染回避）
6. 生存状態を返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[uv__loop_alive確認]
    B --> C{ループ生存?}
    C -->|No| D[uv__update_time]
    C -->|Yes| E{DEFAULTモード?}
    D --> F{r!=0 && stop_flag==0?}
    E -->|Yes| G[uv__update_time + uv__run_timers]
    E -->|No| F
    G --> F
    F -->|No| L[stop_flag リセット]
    F -->|Yes| H[uv__run_pending → uv__run_idle → uv__run_prepare]
    H --> I[uv__io_poll]
    I --> J[uv__run_check → uv__run_closing_handles]
    J --> K[uv__update_time + uv__run_timers + uv__loop_alive]
    K --> M{ONCE/NOWAIT?}
    M -->|Yes| L
    M -->|No| F
    L --> N[rを返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | DEFAULTモード継続 | アクティブなハンドル/リクエストがある限りループを継続する | UV_RUN_DEFAULT |
| BR-02 | ONCEモード | 1回のイテレーション後にbreakする | UV_RUN_ONCE |
| BR-03 | NOWAITモード | I/Oポーリングをブロックせず（timeout=0）、1回のイテレーション後にbreakする | UV_RUN_NOWAIT |
| BR-04 | stop_flag | uv_stop()で設定されたstop_flagが立っている場合、ループを即座に終了する | stop_flag != 0 |
| BR-05 | ループスターベーション防止 | I/Oポーリング後に最大8回まで追加のpending処理を実行する | 常時 |

### 計算ロジック

**I/Oポーリングタイムアウト計算**（`uv__backend_timeout()`）：
- `stop_flag`が立っている場合: 0
- `pending_queue`が空でない場合: 0
- `idle_handles`が空でない場合: 0
- `UV_LOOP_REAP_CHILDREN`フラグが立っている場合: 0
- `closing_handles`がある場合: 0
- 上記以外: `uv__next_timeout(loop)`（次のタイマー期限までの時間）

## データベース操作仕様

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | コールバック内例外 | ユーザーコールバック内でのエラー | ユーザー責任で対処 |

### リトライ仕様

`uv_run()`自体にリトライ機構はない。コールバック内でのエラーはユーザーが処理する。

## トランザクション仕様

該当なし。各フェーズの処理は順序立てて実行されるが、アトミック性は保証されない。

## パフォーマンス要件

- I/Oポーリングのタイムアウトは`uv__backend_timeout()`で最適化されている
- アイドルハンドルが登録されている場合はタイムアウト0でポーリングし、CPU使用率が高くなる
- `can_sleep`判定により、不要なブロッキングを回避している

## セキュリティ考慮事項

- ユーザーコールバック内で長時間ブロックするとイベントループ全体が停止する
- stop_flagのリセットは条件付き代入でキャッシュライン汚染を最小化している

## 備考

- DEFAULTモードでは後方互換性のため、メインループ突入前にタイマー処理を1回実行する
- stop_flagはuv_run()終了時に自動リセットされるため、次回のuv_run()呼び出しは正常に動作する
- 戻り値が非0の場合、まだアクティブなハンドル/リクエストが残っていることを示す

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | **268-272行目**: `uv_run_mode`列挙型。UV_RUN_DEFAULT=0, UV_RUN_ONCE=1, UV_RUN_NOWAIT=2 |
| 1-2 | uv.h | `include/uv.h` | **1941-1956行目**: `uv_loop_s`のstop_flag、active_handles、active_reqs |

**読解のコツ**: `uv_run_mode`の3つのモードの違いを理解することが重要。DEFAULTは全ハンドル終了まで、ONCEは1イテレーション、NOWAITはノンブロッキング1イテレーション。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | core.c | `src/unix/core.c` | **427-492行目**: `uv_run()`の実装本体 |

**主要処理フロー**:
1. **432-434行目**: `uv__loop_alive(loop)`でループ生存確認。生存していない場合は時刻更新のみ
2. **440-443行目**: DEFAULTモード時の初回タイマー処理（後方互換性維持）
3. **445行目**: メインwhile文の条件（`r != 0 && loop->stop_flag == 0`）
4. **446-448行目**: `can_sleep`判定（pending_queueとidle_handlesが空か）
5. **450-452行目**: pending → idle → prepare の順で実行
6. **454-456行目**: タイムアウト計算。ONCE+can_sleepまたはDEFAULTの場合のみ`uv__backend_timeout()`使用
7. **458行目**: メトリクスループカウント増加
8. **460行目**: `uv__io_poll(loop, timeout)` - I/Oポーリング本体
9. **464-465行目**: 追加pending処理（最大8回、スターベーション防止）
10. **472行目**: メトリクスアイドル時間更新
11. **474-478行目**: check → closing → 時刻更新 → タイマー処理
12. **480-482行目**: ループ生存確認、ONCE/NOWAITならbreak
13. **488-489行目**: stop_flagの条件付きリセット

#### Step 3: ループ生存判定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | core.c | `src/unix/core.c` | **393-398行目**: `uv__loop_alive()`の実装。active_handles, active_reqs, pending_queue, closing_handlesの4条件 |

#### Step 4: I/Oポーリングタイムアウトを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | core.c | `src/unix/core.c` | **401-411行目**: `uv__backend_timeout()`の実装。各種条件に応じて0またはuv__next_timeout()を返す |

### プログラム呼び出し階層図

```
uv_run(loop, mode)                       [src/unix/core.c:427]
    |
    +-- uv__loop_alive(loop)              [src/unix/core.c:393]
    |
    +-- uv__update_time(loop)             [src/unix/internal.h:467]
    |
    +-- uv__run_timers(loop)              [src/timer.c]
    |
    +-- [while loop]
    |   +-- uv__run_pending(loop)         [src/unix/core.c]
    |   +-- uv__run_idle(loop)            [src/unix/loop-watcher.c]
    |   +-- uv__run_prepare(loop)         [src/unix/loop-watcher.c]
    |   +-- uv__backend_timeout(loop)     [src/unix/core.c:401]
    |   +-- uv__metrics_inc_loop_count()  [メトリクス]
    |   +-- uv__io_poll(loop, timeout)    [src/unix/kqueue.c or linux.c]
    |   +-- uv__run_pending(loop) x 8     [スターベーション防止]
    |   +-- uv__metrics_update_idle_time()
    |   +-- uv__run_check(loop)           [src/unix/loop-watcher.c]
    |   +-- uv__run_closing_handles(loop) [src/unix/core.c:368]
    |   +-- uv__update_time(loop)
    |   +-- uv__run_timers(loop)
    |   +-- uv__loop_alive(loop)
    |
    └-- return r
```

### データフロー図

```
[入力]                    [処理]                              [出力]

uv_loop_t* loop     -->  メインループ                    -->  int (生存状態)
uv_run_mode mode         |                                    |
                         +-- タイマーコールバック呼び出し      +-- ユーザーコールバック
                         +-- I/Oイベント処理                   |   の実行
                         +-- アイドル/プリペア/チェック          |
                         +-- クロージング処理                   |
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | uv_run()のAPI宣言、uv_run_mode定義 |
| core.c | `src/unix/core.c` | ソース | uv_run()の実装本体、uv__loop_alive()、uv__backend_timeout() |
| internal.h | `src/unix/internal.h` | ヘッダ | uv__update_time()インライン実装 |
| timer.c | `src/timer.c` | ソース | uv__run_timers()の実装 |
| loop-watcher.c | `src/unix/loop-watcher.c` | ソース | uv__run_idle/prepare/checkの実装 |
| kqueue.c | `src/unix/kqueue.c` | ソース | macOSのuv__io_poll()実装 |
| linux.c | `src/unix/linux.c` | ソース | Linuxのuv__io_poll()実装 |
