# 機能設計書 85-Prepare初期化・開始・停止

## 概要

本ドキュメントは、libuvにおけるPrepareハンドルの初期化・開始・停止機能（uv_prepare_init/uv_prepare_start/uv_prepare_stop）の設計仕様を記述する。PrepareハンドルはI/Oポーリングの直前に毎回呼ばれるコールバックを登録するための仕組みである。

### 本機能の処理概要

**業務上の目的・背景**：イベントループのI/Oポーリングフェーズの前に何らかの準備処理を行いたい場合がある。例えば、I/O操作の前にデータバッファの準備、統計情報の収集開始、タイムスタンプの記録などである。Prepareハンドルはこのようなフェーズ特有の処理をフックする手段を提供する。

**機能の利用シーン**：I/Oポーリング前のデータ準備処理、パフォーマンスメトリクスの計測開始、他のライブラリとの統合におけるイベントループフック、デバッグ目的でのループ反復開始の検出などで使用される。

**主要な処理内容**：
1. uv_prepare_init(): ハンドルを初期化し、UV_PREPAREタイプとして登録する
2. uv_prepare_start(): コールバックを設定し、ループのprepare_handlesキューに登録する
3. uv_prepare_stop(): ハンドルをキューから除去し、非アクティブ化する

**関連システム・外部連携**：libuvのイベントループコアと密接に連携する。uv__run_prepare()がイベントループのI/Oポーリング直前に呼ばれ、登録された全Prepareハンドルのコールバックを実行する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 10 | Prepareハンドル | 主機能 | uv_prepare_init()/uv_prepare_start()/uv_prepare_stop()のAPI定義 |

## 機能種別

イベントフック / コールバック管理

## 入力仕様

### 入力パラメータ

#### uv_prepare_init

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| loop | uv_loop_t* | Yes | イベントループ | NULLであってはならない |
| prepare | uv_prepare_t* | Yes | 初期化対象のPrepareハンドル | NULLであってはならない |

#### uv_prepare_start

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| prepare | uv_prepare_t* | Yes | 対象のPrepareハンドル | NULLであってはならない |
| cb | uv_prepare_cb | Yes | コールバック関数 | NULLの場合UV_EINVALを返す |

#### uv_prepare_stop

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| prepare | uv_prepare_t* | Yes | 対象のPrepareハンドル | NULLであってはならない |

### 入力データソース

呼び出し元のアプリケーションコードから直接渡される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値（各関数共通） | int | 成功時0、エラー時UV_EINVAL |

### 出力先

呼び出し元への戻り値。副作用としてループのprepare_handlesキューの更新が行われる。

## 処理フロー

### 処理シーケンス

```
uv_prepare_init:
1. uv__handle_init()でハンドルをUV_PREPAREとして初期化
2. prepare_cbをNULLに初期化

uv_prepare_start:
1. uv__is_active()でアクティブチェック（既にアクティブなら何もしない）
2. cbがNULLならUV_EINVALを返す
3. loop->prepare_handlesキューの先頭にハンドルを挿入
4. prepare_cbにcbを設定
5. uv__handle_start()でハンドルをアクティブ化

uv_prepare_stop:
1. uv__is_active()で非アクティブチェック（非アクティブなら何もしない）
2. uv__queue_remove()でキューから除去
3. uv__handle_stop()で非アクティブ化
```

### フローチャート

```mermaid
flowchart TD
    subgraph init
    A1[uv_prepare_init] --> B1[uv__handle_init UV_PREPARE]
    B1 --> C1[prepare_cb = NULL]
    C1 --> D1[return 0]
    end

    subgraph start
    A2[uv_prepare_start] --> B2{is_active?}
    B2 -->|Yes| C2[return 0]
    B2 -->|No| D2{cb == NULL?}
    D2 -->|Yes| E2[return UV_EINVAL]
    D2 -->|No| F2[キューに挿入]
    F2 --> G2[prepare_cb = cb]
    G2 --> H2[uv__handle_start]
    H2 --> I2[return 0]
    end

    subgraph stop
    A3[uv_prepare_stop] --> B3{is_active?}
    B3 -->|No| C3[return 0]
    B3 -->|Yes| D3[uv__queue_remove]
    D3 --> E3[uv__handle_stop]
    E3 --> F3[return 0]
    end
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-85-01 | 冪等性（start） | 既にアクティブなハンドルに対するstart呼び出しは何もしない | startが二重呼び出しされた場合 |
| BR-85-02 | 冪等性（stop） | 非アクティブなハンドルに対するstop呼び出しは何もしない | stopが二重呼び出しされた場合 |
| BR-85-03 | NULLコールバック拒否 | startのcb引数がNULLの場合UV_EINVALを返す | cb == NULLの場合 |
| BR-85-04 | 実行タイミング | Prepareコールバックは各イベントループ反復のI/Oポーリング直前に実行される | ハンドルがアクティブな場合 |

### 計算ロジック

特になし。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | 無効引数 | uv_prepare_start()のcb引数がNULL | 有効なコールバック関数を渡す |

### リトライ仕様

リトライ不要。

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

トランザクション制御なし。

## パフォーマンス要件

- init/start/stop: いずれもO(1)の定数時間操作
- コールバック実行（uv__run_prepare）: O(n)（nは登録ハンドル数）

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

特になし。

## 備考

- Prepare/Check/Idleの3種類のloop watcherは、UV_LOOP_WATCHER_DEFINEマクロで統一的に実装されている。
- PrepareはI/Oポーリング前、CheckはI/Oポーリング後に呼ばれる点が異なる。
- uv__run_prepare()実行時、キューの各要素は一度取り出されてからキュー末尾に再挿入される。これによりコールバック内で新たにPrepareハンドルを追加しても安全に動作する。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | **925-928行目**: uv_prepare_s構造体。UV_HANDLE_FIELDSとUV_PREPARE_PRIVATE_FIELDSで構成 |

**読解のコツ**: Prepare/Check/Idleは同じパターンの構造体で、プライベートフィールドにコールバック関数とキューノードを持つ。

#### Step 2: エントリーポイントを理解する（マクロ展開）

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | loop-watcher.c | `src/unix/loop-watcher.c` | **25-64行目**: UV_LOOP_WATCHER_DEFINEマクロの定義。init/start/stop/run/closeの5関数を一括定義 |
| 2-2 | loop-watcher.c | `src/unix/loop-watcher.c` | **66行目**: `UV_LOOP_WATCHER_DEFINE(prepare, PREPARE)` によりprepare用関数群が展開される |

**主要処理フロー**:
- **26-30行目（展開後）**: init - uv__handle_init()とcb=NULLの設定
- **32-39行目（展開後）**: start - アクティブチェック、NULLチェック、キュー挿入、cb設定、アクティブ化
- **41-46行目（展開後）**: stop - アクティブチェック、キュー除去、非アクティブ化
- **48-60行目（展開後）**: run - キュー全要素の移動、コールバック実行、キュー末尾への再挿入

#### Step 3: マクロの動作パターンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | loop-watcher.c | `src/unix/loop-watcher.c` | **35行目**: キュー先頭へ挿入（uv__queue_insert_head） |
| 3-2 | loop-watcher.c | `src/unix/loop-watcher.c` | **52行目**: uv__run_prepare内でキュー全体を移動（uv__queue_move） |
| 3-3 | loop-watcher.c | `src/unix/loop-watcher.c` | **57行目**: 各要素をloop->prepare_handlesの末尾に再挿入 |

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

```
uv_prepare_init(loop, prepare)
    +-- uv__handle_init(loop, handle, UV_PREPARE)
    +-- prepare_cb = NULL

uv_prepare_start(prepare, cb)
    +-- [既アクティブ] --> return 0
    +-- [cb == NULL] --> return UV_EINVAL
    +-- uv__queue_insert_head(&loop->prepare_handles, &handle->queue)
    +-- prepare_cb = cb
    +-- uv__handle_start(handle)

uv_prepare_stop(prepare)
    +-- [非アクティブ] --> return 0
    +-- uv__queue_remove(&handle->queue)
    +-- uv__handle_stop(handle)

uv__run_prepare(loop)  [イベントループから呼ばれる]
    +-- uv__queue_move(&loop->prepare_handles, &queue)
    +-- while (!empty)
            +-- uv__queue_data() でハンドル取得
            +-- uv__queue_insert_tail() でループキューに戻す
            +-- prepare_cb(h) コールバック実行
```

### データフロー図

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

uv_loop_t*,      
uv_prepare_t* ───> uv_prepare_init()     ───> int (0)
                       |
uv_prepare_t*,       
uv_prepare_cb ───> uv_prepare_start()    ───> int (0 or UV_EINVAL)
                       |
                   prepare_handles キュー
                       |
uv__run_prepare()      |
  (イベントループ) ───> コールバック実行   ───> ユーザー処理
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | API宣言（930-932行目）、uv_prepare_s構造体定義（925-928行目） |
| loop-watcher.c | `src/unix/loop-watcher.c` | ソース | UV_LOOP_WATCHER_DEFINEマクロによる実装（25-68行目） |
| uv-common.h | `src/uv-common.h` | ヘッダ | uv__handle_init/start/stopマクロ定義 |
