# 機能設計書 182-ライブラリシャットダウン

## 概要

本ドキュメントは、libuvが確保した内部リソースを解放する`uv_library_shutdown()` APIの機能設計について記述する。プロセス終了時やlibuv利用完了後に呼び出すことで、内部で確保されたメモリやリソースをクリーンアップする。

### 本機能の処理概要

**業務上の目的・背景**：libuvはグローバルスコープでさまざまな内部リソース（プロセスタイトル用メモリ、シグナルハンドラ、スレッドプール）を確保している。これらのリソースはプロセス終了時にOSによって回収されるが、Valgrindなどのメモリリーク検出ツールで誤検知が発生する原因となる。`uv_library_shutdown()`を呼び出すことで、これらの内部リソースを明示的に解放し、クリーンなシャットダウンを実現する。また、GCC/Clang環境ではデストラクタ属性により自動的に呼び出される仕組みも持つ。

**機能の利用シーン**：
- プロセス終了前のクリーンアップ処理
- Valgrind等のメモリリーク検出ツール使用時のリーク誤検知防止
- ライブラリの動的アンロード前のリソース解放
- テストフレームワークでのリソースリーク検出

**主要な処理内容**：
1. 多重呼び出し防止チェック（アトミックな状態フラグの交換）
2. プロセスタイトル関連メモリの解放（`uv__process_title_cleanup()`）
3. シグナルハンドラ関連リソースの解放（`uv__signal_cleanup()`）
4. スレッドプールの停止とリソース解放（`uv__threadpool_cleanup()`）

**関連システム・外部連携**：GCC/Clang環境では`__attribute__((destructor))`により、共有ライブラリのアンロード時やプログラム終了時に自動的に呼び出される。Windowsではスレッドが既にOSにより終了されているため、デストラクタとしては登録されない。

**権限による制御**：なし。ただし、この関数の呼び出し後はlibuvのAPIを使用してはならない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | その他ユーティリティ | 主機能 | uv_library_shutdown()による内部リソース解放のAPI定義 |

## 機能種別

リソース解放処理（クリーンアップ）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| （なし） | void | - | パラメータなし | - |

### 入力データソース

なし。内部状態のみを参照する。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| （なし） | void | 戻り値なし |

### 出力先

なし。副作用として内部リソースが解放される。

## 処理フロー

### 処理シーケンス

```
1. 多重呼び出し防止チェック
   └─ was_shutdownフラグをアトミックに1と交換し、既に1であった場合は即座にreturn
2. プロセスタイトルクリーンアップ
   └─ uv__process_title_cleanup()を呼び出し、uv_setup_args()で確保したメモリを解放
3. シグナルクリーンアップ
   └─ uv__signal_cleanup()を呼び出し、シグナル関連リソースを解放
4. スレッドプールクリーンアップ（非z/OS環境）
   └─ uv__threadpool_cleanup()を呼び出し、スレッドプールを停止・リソース解放
   ※ z/OS環境ではuv__os390_cleanup()が呼ばれる
```

### フローチャート

```mermaid
flowchart TD
    A[開始: uv_library_shutdown] --> B{was_shutdown<br/>フラグ交換}
    B -->|既にシャットダウン済み| C[即座にreturn]
    B -->|初回呼び出し| D[uv__process_title_cleanup]
    D --> E[uv__signal_cleanup]
    E --> F{__MVS__<br/>定義済み?}
    F -->|Yes| G[uv__os390_cleanup]
    F -->|No| H[uv__threadpool_cleanup]
    G --> I[終了]
    H --> I
    C --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-182-1 | 一度だけ実行 | was_shutdownフラグにより多重呼び出しが防止される | 常に適用 |
| BR-182-2 | 呼び出し後の使用禁止 | シャットダウン後はlibuv APIの使用は未定義動作 | シャットダウン後 |
| BR-182-3 | 自動呼び出し | GCC/Clang環境ではdestructor属性により自動的に呼ばれる | GCC/Clang, 非Windows環境 |
| BR-182-4 | Windows非対応 | Windows環境ではdestructor属性は付与されない（スレッド安全性のため） | Windows環境 |

### 計算ロジック

特になし。

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

### 操作別データベース影響一覧

該当なし（データベースを使用しない）。

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| （なし） | - | エラーは発生しない | - |

### リトライ仕様

不要。多重呼び出しは安全に無視される（was_shutdownフラグによる防御）。

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

該当なし。アトミック操作（`uv__exchange_int_relaxed`）により多重呼び出しが防止される。

## パフォーマンス要件

スレッドプールのクリーンアップではスレッドのjoinを待つため、スレッドプールのワーカースレッドがすべて終了するまでブロックする可能性がある。

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

- シャットダウン後にlibuvのAPIを呼び出すと未定義動作になるため、アプリケーションの終了フェーズでのみ使用すべき
- スレッドプールのクリーンアップは全ワーカースレッドの終了を待つため、デッドロックの可能性に注意

## 備考

- `uv__exchange_int_relaxed`は、MSVCでは`InterlockedExchangeNoFence`、GCC/Clangでは`atomic_exchange_explicit`（`memory_order_relaxed`）にマッピングされる
- z/OS（`__MVS__`）環境では`uv__threadpool_cleanup()`の代わりに`uv__os390_cleanup()`が呼ばれる
- GCC/Clang環境での`__attribute__((destructor))`は、`uv__threadpool_cleanup()`にも`__MVS__`環境で設定されている

---

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

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

### 推奨読解順序

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

多重呼び出し防止のアトミック操作マクロを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv-common.h | `src/uv-common.h` | uv__exchange_int_relaxedマクロの定義（MSVC/GCC/Clang差異） |

**読解のコツ**: `uv__exchange_int_relaxed`はアトミックな整数交換を行うマクロである。MSVCでは`InterlockedExchangeNoFence`、それ以外では`atomic_exchange_explicit`で`memory_order_relaxed`を使用している。relaxedメモリオーダーを使用しているのは、この操作が他の変数との順序関係を必要としないためである。

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

`uv_library_shutdown()`の実装を読み解く。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv-common.c | `src/uv-common.c` | uv_library_shutdown()の実装（多重呼び出し防止、クリーンアップ呼び出し） |

**主要処理フロー**:
1. **971-973行目**: GCC/Clang環境ではdestructor属性が付与される（Windows以外）
2. **974行目**: `uv_library_shutdown()`関数定義
3. **975行目**: `static int was_shutdown` - 多重呼び出し防止用フラグ
4. **977-978行目**: アトミック交換で既にシャットダウン済みならreturn
5. **980行目**: `uv__process_title_cleanup()` - プロセスタイトル用メモリ解放
6. **981行目**: `uv__signal_cleanup()` - シグナル関連リソース解放
7. **982-987行目**: プラットフォーム別のスレッドプールクリーンアップ

#### Step 3: プロセスタイトルクリーンアップを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | proctitle.c | `src/unix/proctitle.c` | uv__process_title_cleanup()の実装 |

**主要処理フロー**:
- **154-157行目**: `args_mem`（`uv_setup_args()`で確保されたメモリ）をfreeしてNULLに設定

#### Step 4: スレッドプールクリーンアップを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | threadpool.c | `src/threadpool.c` | uv__threadpool_cleanup()の実装 |

**主要処理フロー**:
- **168行目**: `uv__threadpool_cleanup()`関数定義
- **171-172行目**: `nthreads == 0`なら即座にreturn（スレッドプール未初期化）
- **176行目**: exit_messageをワークキューに投入（スレッド終了指示）
- **179-181行目**: 全ワーカースレッドのjoinを待機
- **183-184行目**: カスタムメモリの解放（default_threads以外の場合）
- **186-187行目**: ミューテックスとコンディション変数の破棄
- **189-190行目**: threads/nthreadsのリセット

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

```
uv_library_shutdown()                      [src/uv-common.c:974-988]
    |
    +-- uv__exchange_int_relaxed()          [src/uv-common.h:70-74] (多重呼び出し防止)
    |
    +-- uv__process_title_cleanup()         [src/unix/proctitle.c:154-157]
    |      +-- uv__free(args_mem)
    |
    +-- uv__signal_cleanup()                [src/unix/signal.c] (シグナル関連解放)
    |
    +-- uv__threadpool_cleanup()            [src/threadpool.c:168-191] (非z/OS)
           +-- post(&exit_message)          [src/threadpool.c:143-161]
           +-- uv_thread_join()             (全ワーカースレッドのjoin)
           +-- uv__free(threads)            (カスタムメモリの場合)
           +-- uv_mutex_destroy(&mutex)
           +-- uv_cond_destroy(&cond)
```

### データフロー図

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

(なし) ---------> uv_library_shutdown() ----------> (なし/副作用のみ)
                       |
                       v
                  was_shutdownフラグ
                  (static int)
                       |
                 +-----+--------+------------------+
                 v              v                  v
          process_title   signal_handler    threadpool
          メモリ解放       リソース解放       停止・解放
          (args_mem)                        (exit_message -> join)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | uv_library_shutdown()のAPI宣言（283行目） |
| uv-common.c | `src/uv-common.c` | ソース | uv_library_shutdown()の実装（974-988行目） |
| uv-common.h | `src/uv-common.h` | 内部ヘッダー | uv__exchange_int_relaxedマクロ定義（69-75行目）、クリーンアップ関数宣言（239-241行目） |
| proctitle.c | `src/unix/proctitle.c` | ソース | uv__process_title_cleanup()の実装（154-157行目） |
| signal.c | `src/unix/signal.c` | ソース | uv__signal_cleanup()の実装 |
| threadpool.c | `src/threadpool.c` | ソース | uv__threadpool_cleanup()の実装（168-191行目） |
