# 機能設計書 15-ハンドルクローズ

## 概要

`uv_close()`によりハンドルを閉じてリソースを解放する機能の設計書である。

### 本機能の処理概要

**業務上の目的・背景**：libuvで使用するすべてのハンドルは、不要になった際に明示的にクローズする必要がある。`uv_close()`はハンドルのクローズ処理を開始し、ハンドル固有のリソース（ファイルディスクリプタ、ソケット等）を解放する。クローズ完了後にコールバックが呼ばれるため、ハンドルのメモリ解放はコールバック内で行うことが推奨される。

**機能の利用シーン**：TCPソケットの切断、タイマーの破棄、ファイル監視の終了など、すべてのハンドル型のライフサイクル終了時に使用される。イベントループ終了前に全ハンドルをクローズしなければリソースリークが発生する。

**主要な処理内容**：
1. ハンドルにUV_HANDLE_CLOSINGフラグをセットする
2. クローズコールバックを保存する
3. ハンドル型に応じた固有のクローズ処理を呼び出す（TCP、UDP、パイプ等）
4. クローズ保留リストに追加する（`uv__make_close_pending()`）
5. 次回イベントループイテレーションでクローズを完了し、コールバックを呼ぶ

**関連システム・外部連携**：OS固有のリソース（ファイルディスクリプタ、ソケット）の解放を伴う。各ハンドル型固有のクローズ処理と連携する。

**権限による制御**：特になし。ハンドルのオーナーが呼び出す。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 7 | ハンドル基底 | 主機能 | uv_close()によるハンドルクローズ・リソース解放のAPI定義 |
| 2 | 設計概要 | 補助機能 | ハンドル・リクエストのライフサイクル管理の概念説明 |
| 33 | 基本事項 | 補助機能 | uv_close()を使ったハンドルライフサイクル管理の説明 |
| 42 | 0.10→1.0.0マイグレーション | 補助機能 | uv_close()の使用方法変更の説明 |

## 機能種別

リソース解放・状態遷移

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | uv_handle_t* | Yes | クローズ対象のハンドル | クローズ中でないこと（assert） |
| close_cb | uv_close_cb | No | クローズ完了時に呼ばれるコールバック | NULLも許容（コールバックなし） |

### 入力データソース

呼び出し元から渡されるハンドル構造体ポインタとコールバック関数ポインタ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (なし) | void | 戻り値なし |

### 出力先

ハンドル構造体のflagsフィールドとclose_cbフィールドを更新。ループのclosing_handlesリストに追加。

## 処理フロー

### 処理シーケンス

```
1. uv_close()が呼び出される
   └─ assert(!uv__is_closing(handle)) でクローズ中でないことを確認
2. UV_HANDLE_CLOSINGフラグをセット
3. close_cbを保存
4. ハンドル型に応じたクローズ処理を呼び出す
   ├─ UV_NAMED_PIPE → uv__pipe_close()
   ├─ UV_TTY → uv__tty_close()
   ├─ UV_TCP → uv__tcp_close()
   ├─ UV_UDP → uv__udp_close()
   ├─ UV_PREPARE → uv__prepare_close()
   ├─ UV_CHECK → uv__check_close()
   ├─ UV_IDLE → uv__idle_close()
   ├─ UV_ASYNC → uv__async_close()
   ├─ UV_TIMER → uv__timer_close()
   ├─ UV_PROCESS → uv__process_close()
   ├─ UV_FS_EVENT → uv__fs_event_close()
   ├─ UV_POLL → uv__poll_close()
   ├─ UV_FS_POLL → uv__fs_poll_close() (即return)
   └─ UV_SIGNAL → uv__signal_close()
5. uv__make_close_pending()でclosing_handlesリストに追加
6. 次回ループイテレーションでuv__finish_close()が呼ばれる
   └─ UV_HANDLE_CLOSEDフラグをセット
   └─ ハンドルキューから削除
   └─ close_cb()を呼び出す
```

### フローチャート

```mermaid
flowchart TD
    A[uv_close 呼び出し] --> B[CLOSINGフラグセット]
    B --> C[close_cb保存]
    C --> D{ハンドル型による分岐}
    D -->|TCP| E1[uv__tcp_close]
    D -->|UDP| E2[uv__udp_close]
    D -->|Timer| E3[uv__timer_close]
    D -->|その他| E4[各型固有クローズ]
    E1 --> F[uv__make_close_pending]
    E2 --> F
    E3 --> F
    E4 --> F
    F --> G[closing_handlesリストに追加]
    G --> H[次回ループで完了処理]
    H --> I[close_cb呼び出し]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-15-01 | 二重クローズ禁止 | 既にクローズ中のハンドルに対するuv_close()はassertで停止する | 常時 |
| BR-15-02 | 非同期完了 | クローズ処理は非同期で完了し、コールバックは次回ループイテレーション以降に呼ばれる | 常時 |
| BR-15-03 | メモリ管理 | ハンドルのメモリ解放はclose_cb内で行うべき | 常時 |
| BR-15-04 | FS_POLL/FS_EVENT特殊処理 | FS_POLLとFS_EVENT(Solaris/z/OS)はmake_close_pendingを即座に呼ばず、内部処理完了後に呼ぶ | 特定ハンドル型 |

### 計算ロジック

特になし。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| assert失敗 | プログラムエラー | 既にクローズ中のハンドルに対して呼び出した場合 | コードを修正し二重クローズを防ぐ |

### リトライ仕様

リトライ不要（一度だけ呼ぶべき）。

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

該当なし。

## パフォーマンス要件

O(1)の定数時間（クローズ開始のみ）。実際のリソース解放は次回ループイテレーションで行われる。

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

ファイルディスクリプタやソケットのクローズを伴うため、リソースリーク防止の観点から確実にクローズを行うべきである。

## 備考

- uv_close()呼び出し後もハンドルのメモリは有効であり、コールバックが呼ばれるまで解放してはならない
- FS_POLLハンドルは内部FSリクエストが完了するまでクローズが遅延する場合がある
- 参照: include/uv.h L504

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv-common.h | `src/uv-common.h` | **L82-83**: UV_HANDLE_CLOSINGフラグ(0x01)とUV_HANDLE_CLOSEDフラグ(0x02)の定義 |
| 1-2 | uv.h | `include/uv.h` | **L470**: close_cbフィールドの定義。クローズコールバックを保持する |

**読解のコツ**: `uv__is_closing()`マクロは`UV_HANDLE_CLOSING | UV_HANDLE_CLOSED`の両方をチェックする（L277-278）。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | core.c | `src/unix/core.c` | **L159-238**: uv_close()のUnix実装。ハンドル型による大きなswitch文 |

**主要処理フロー**:
1. **160行目**: `assert(!uv__is_closing(handle))` で二重クローズチェック
2. **162行目**: `handle->flags |= UV_HANDLE_CLOSING` でフラグセット
3. **163行目**: `handle->close_cb = close_cb` でコールバック保存
4. **165-235行目**: switch文でハンドル型ごとのクローズ処理を呼び出し
5. **237行目**: `uv__make_close_pending(handle)` でclosing_handlesリストに追加

#### Step 3: クローズ完了処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | core.c | `src/unix/core.c` | **L268-273**: `uv__make_close_pending()`。closing_handlesリストの先頭に追加 |
| 3-2 | core.c | `src/unix/core.c` | **L303-365**: `uv__finish_close()`。CLOSEDフラグセット、型固有のデストラクション、コールバック呼び出し |
| 3-3 | core.c | `src/unix/core.c` | **L368-380**: `uv__run_closing_handles()`。closing_handlesリストを走査して完了処理 |

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

```
uv_close(handle, close_cb)              [src/unix/core.c:159]
    │
    ├─ handle->flags |= UV_HANDLE_CLOSING
    ├─ handle->close_cb = close_cb
    │
    ├─ uv__tcp_close() / uv__udp_close() / ...  [型固有クローズ]
    │
    └─ uv__make_close_pending(handle)    [src/unix/core.c:268]
           └─ closing_handlesリストに追加

[次回ループイテレーション]
uv__run_closing_handles(loop)            [src/unix/core.c:368]
    └─ uv__finish_close(handle)          [src/unix/core.c:303]
           ├─ handle->flags |= UV_HANDLE_CLOSED
           ├─ uv__stream_destroy() 等    [型固有デストラクション]
           ├─ uv__handle_unref(handle)
           ├─ uv__queue_remove()
           └─ handle->close_cb(handle)   [コールバック呼び出し]
```

### データフロー図

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

uv_handle_t* handle ──────> CLOSINGフラグセット ─────────> handle->flags更新
uv_close_cb close_cb ─────> 型固有クローズ処理 ─────────> OSリソース解放
                            closing_handlesに追加 ────────> loop->closing_handles更新
                            [次回ループ]
                            finish_close処理 ──────────> close_cb呼び出し
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | 公開API宣言（L504） |
| core.c (unix) | `src/unix/core.c` | ソース | Unix実装（L159-238, L268-380） |
| uv-common.h | `src/uv-common.h` | ヘッダ | フラグ定義（L82-83）、uv__is_closingマクロ（L277-278） |
| handle.c (win) | `src/win/handle.c` | ソース | Windows実装 |
