# 機能設計書 18-ハンドル走査

## 概要

`uv_walk()`によりイベントループに登録された全ハンドルを走査する機能の設計書である。

### 本機能の処理概要

**業務上の目的・背景**：イベントループに登録された全ハンドルを列挙し、各ハンドルに対してコールバック関数を実行する機能を提供する。イベントループの終了前に全ハンドルをクローズする場合や、デバッグ目的でハンドルの状態を確認する場合に不可欠な機能である。

**機能の利用シーン**：イベントループ終了前の全ハンドルクローズ処理、デバッグ時のハンドル一覧取得、リソースリーク検出、ヘルスチェック処理などに使用される。`uv_loop_close()`を呼ぶ前に全ハンドルをクローズすることがlibuvの慣例パターンであり、`uv_walk()`はそのための走査手段を提供する。

**主要な処理内容**：
1. ループの`handle_queue`（二重リンクリスト）を走査する
2. 各ハンドルについてUV_HANDLE_INTERNALフラグがセットされていればスキップする
3. 非内部ハンドルに対してwalk_cbコールバックを呼び出す
4. 走査中にコールバック内でハンドルがクローズされても安全に動作する

**関連システム・外部連携**：特になし。ループ内部のハンドルキューを走査する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | イベントループ | 主機能 | uv_walk()による登録済み全ハンドルの走査のAPI定義 |

## 機能種別

データ走査・コールバック実行

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| loop | uv_loop_t* | Yes | 対象のイベントループ | NULLチェックなし |
| walk_cb | uv_walk_cb | Yes | 各ハンドルに対して呼ばれるコールバック | NULLチェックなし |
| arg | void* | No | コールバックに渡されるユーザーデータ | NULLも許容 |

### 入力データソース

呼び出し元から渡されるイベントループ、コールバック関数、ユーザーデータ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (なし) | void | 戻り値なし。コールバックを通じてハンドル情報を提供 |

### 出力先

walk_cbコールバックへの引数として各ハンドルポインタを渡す。

## 処理フロー

### 処理シーケンス

```
1. uv_walk()が呼び出される
2. handle_queueの内容を一時キューに移動（安全な走査のため）
3. 一時キューを先頭から走査
   3a. ハンドルを一時キューから取り出す
   3b. 元のhandle_queueの末尾に再挿入
   3c. UV_HANDLE_INTERNALフラグがセットされていればスキップ
   3d. walk_cb(handle, arg)を呼び出す
4. 全ハンドル走査完了
```

### フローチャート

```mermaid
flowchart TD
    A[uv_walk 呼び出し] --> B[handle_queueを一時キューに移動]
    B --> C{一時キュー空?}
    C -->|Yes| G[終了]
    C -->|No| D[ハンドルを取り出し<br>handle_queueに再挿入]
    D --> E{INTERNALフラグ?}
    E -->|Yes| C
    E -->|No| F[walk_cb呼び出し]
    F --> C
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-18-01 | 内部ハンドルスキップ | UV_HANDLE_INTERNALフラグがセットされたハンドルはコールバックに渡されない | 常時 |
| BR-18-02 | 安全な走査 | handle_queueの移動により、コールバック内でハンドル操作が行われても安全に走査が継続される | 常時 |
| BR-18-03 | 順序保証 | ハンドルはhandle_queueに登録された順序で走査される | 常時 |

### 計算ロジック

特になし。

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

該当なし。

## エラー処理

### エラーケース一覧

本関数はエラーを返さない。

### リトライ仕様

リトライ不要。

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

該当なし。

## パフォーマンス要件

O(n)（nはループに登録されたハンドル数）。全ハンドルを走査するため、ハンドル数に比例する。

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

特になし。

## 備考

- `uv_walk()`のコールバック内でuv_close()を呼ぶことは安全である（キュー移動方式により）
- `uv_print_all_handles()`と`uv_print_active_handles()`は内部的に類似のロジックを使用する
- 参照: include/uv.h L498

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | **L1946**: `uv_loop_s`構造体の`handle_queue`フィールド。uv__queue型の二重リンクリスト |
| 1-2 | uv.h | `include/uv.h` | **L471**: UV_HANDLE_FIELDS内の`handle_queue`。各ハンドルがキューのノードとなる |

**読解のコツ**: libuvは`struct uv__queue`（二重リンクリスト）を多用する。`uv__queue_data()`マクロでキューノードからハンドル構造体のポインタを取得する（`container_of`パターン）。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv.h | `include/uv.h` | **L498**: uv_walk()のAPI宣言 |
| 2-2 | uv-common.c | `src/uv-common.c` | **L554-570**: uv_walk()の実装 |

**主要処理フロー**:
1. **559行目**: `uv__queue_move(&loop->handle_queue, &queue)` でキューを一時移動
2. **560行目**: `while (!uv__queue_empty(&queue))` ループ開始
3. **561行目**: `uv__queue_head(&queue)` で先頭要素取得
4. **562行目**: `uv__queue_data(q, uv_handle_t, handle_queue)` でハンドルポインタ取得
5. **564行目**: `uv__queue_remove(q)` で一時キューから削除
6. **565行目**: `uv__queue_insert_tail(&loop->handle_queue, q)` で元のキューに再挿入
7. **567行目**: `UV_HANDLE_INTERNAL`フラグチェック
8. **568行目**: `walk_cb(h, arg)` でコールバック呼び出し

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

```
uv_walk(loop, walk_cb, arg)          [src/uv-common.c:554]
    │
    ├─ uv__queue_move()              [handle_queueを一時キューに移動]
    │
    └─ while(!uv__queue_empty)       [一時キュー走査ループ]
           │
           ├─ uv__queue_head()       [先頭要素取得]
           ├─ uv__queue_data()       [ハンドルポインタ取得]
           ├─ uv__queue_remove()     [一時キューから削除]
           ├─ uv__queue_insert_tail()[元キューに再挿入]
           │
           └─ walk_cb(h, arg)        [コールバック呼び出し]
```

### データフロー図

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

uv_loop_t* loop ────────────> handle_queue走査 ──────────> walk_cb(handle, arg)
uv_walk_cb walk_cb ─────────> INTERNALフィルタ            各ハンドルへのコールバック
void* arg ──────────────────> コールバック引数渡し
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | 公開API宣言（L498） |
| uv-common.c | `src/uv-common.c` | ソース | 実装（L554-570） |
| uv-common.h | `src/uv-common.h` | ヘッダ | UV_HANDLE_INTERNALフラグ定義（L86） |
| queue.h | `src/queue.h` | ヘッダ | uv__queueデータ構造のマクロ定義 |
