# 機能設計書 87-Idle初期化・開始・停止

## 概要

本ドキュメントは、libuvにおけるIdleハンドルの初期化・開始・停止機能（uv_idle_init/uv_idle_start/uv_idle_stop）の設計仕様を記述する。Idleハンドルはイベントループの各反復で呼ばれるコールバックを登録する仕組みで、アクティブなIdleハンドルが存在する限りI/Oポーリングのタイムアウトは0になる。

### 本機能の処理概要

**業務上の目的・背景**：イベントループが他の処理を待つ間に、バックグラウンド処理を行いたい場合がある。Idleハンドルはループの反復ごとに呼ばれるため、低優先度のバックグラウンドタスク（ガベージコレクション、統計収集など）に適している。ただし、アクティブなIdleハンドルがあるとループはI/O待ちでブロックしなくなるため、CPU使用率に影響することに注意が必要である。

**機能の利用シーン**：バックグラウンドでの軽量タスクの実行、CPUバウンド処理の段階的実行、デバッグやプロファイリング用のフック、イベントループのビジー検出などで使用される。

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

**関連システム・外部連携**：libuvのイベントループコアと密接に連携する。uv__run_idle()がイベントループの各反復で呼ばれる。アクティブなIdleハンドルが存在するとuv_backend_timeout()が0を返し、I/Oポーリングがノンブロッキングになる。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | Idleハンドル | 主機能 | uv_idle_init()/uv_idle_start()/uv_idle_stop()のAPI定義 |
| 33 | 基本事項 | 補助機能 | Idleハンドルのサンプルコードを使った基本動作の解説 |
| 39 | ユーティリティ | 補助機能 | アイドルハンドルのサンプルコード解説 |

## 機能種別

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

## 入力仕様

### 入力パラメータ

#### uv_idle_init

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

#### uv_idle_start

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

#### uv_idle_stop

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

### 入力データソース

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

## 出力仕様

### 出力データ

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

### 出力先

呼び出し元への戻り値。

## 処理フロー

### 処理シーケンス

```
uv_idle_init:
1. uv__handle_init()でハンドルをUV_IDLEとして初期化
2. idle_cbをNULLに初期化

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

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

### フローチャート

```mermaid
flowchart TD
    subgraph init
    A1[uv_idle_init] --> B1[uv__handle_init UV_IDLE]
    B1 --> C1[idle_cb = NULL]
    C1 --> D1[return 0]
    end

    subgraph start
    A2[uv_idle_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[idle_cb = cb]
    G2 --> H2[uv__handle_start]
    H2 --> I2[return 0]
    end

    subgraph stop
    A3[uv_idle_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-87-01 | 冪等性（start） | 既にアクティブなハンドルに対するstart呼び出しは何もしない | start二重呼び出し時 |
| BR-87-02 | 冪等性（stop） | 非アクティブなハンドルに対するstop呼び出しは何もしない | stop二重呼び出し時 |
| BR-87-03 | NULLコールバック拒否 | startのcb引数がNULLの場合UV_EINVALを返す | cb == NULLの場合 |
| BR-87-04 | ループ非ブロック化 | アクティブなIdleハンドルが存在するとI/Oポーリングタイムアウトが0になる | ハンドルがアクティブな場合 |

### 計算ロジック

特になし。

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

該当なし。

## エラー処理

### エラーケース一覧

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

### リトライ仕様

リトライ不要。

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

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

## パフォーマンス要件

- init/start/stop: O(1)
- コールバック実行（uv__run_idle）: O(n)
- 注意: アクティブなIdleハンドルが存在するとイベントループがスピンし、CPU使用率が上昇する

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

特になし。

## 備考

- Idleハンドルは名前に反して「アイドル時」だけでなく、イベントループの各反復で必ず呼ばれる。
- PrepareやCheckとの違いは、IdleがアクティブだとI/Oポーリングがブロックしなくなる点である。
- 実装はPrepare/Checkと同じUV_LOOP_WATCHER_DEFINEマクロで行われる。

---

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

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

### 推奨読解順序

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

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | loop-watcher.c | `src/unix/loop-watcher.c` | **25-64行目**: UV_LOOP_WATCHER_DEFINEマクロ |
| 2-2 | loop-watcher.c | `src/unix/loop-watcher.c` | **68行目**: `UV_LOOP_WATCHER_DEFINE(idle, IDLE)` による展開 |

**主要処理フロー**:
- マクロ展開により、uv_idle_init/uv_idle_start/uv_idle_stop/uv__run_idle/uv__idle_closeが生成される
- Prepare/Checkと完全に同じ構造

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

```
uv_idle_init(loop, idle)
    +-- uv__handle_init(loop, handle, UV_IDLE)

uv_idle_start(idle, cb)
    +-- uv__queue_insert_head(&loop->idle_handles, &handle->queue)
    +-- uv__handle_start(handle)

uv_idle_stop(idle)
    +-- uv__queue_remove(&handle->queue)
    +-- uv__handle_stop(handle)

uv__run_idle(loop)  [イベントループから呼ばれる]
    +-- キュー走査 -> コールバック実行
```

### データフロー図

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

uv_idle_t*,
uv_idle_cb ────> uv_idle_start()         ───> idle_handles キューに登録

イベントループ ──> uv__run_idle()         ───> コールバック実行
  (各反復)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | API宣言（950-952行目）、構造体定義（945-948行目） |
| loop-watcher.c | `src/unix/loop-watcher.c` | ソース | マクロ展開による実装（68行目） |
