# 機能設計書 132-ミューテックス

## 概要

uv_mutex_init()/uv_mutex_init_recursive()/uv_mutex_destroy()/uv_mutex_lock()/uv_mutex_trylock()/uv_mutex_unlock()によりミューテックス（相互排他ロック）を制御する機能の設計書である。

### 本機能の処理概要

本機能は、マルチスレッド環境における排他制御のための基本的な同期プリミティブであるミューテックスのクロスプラットフォームAPIを提供する。

**業務上の目的・背景**：マルチスレッドプログラミングにおいて、共有リソースへの同時アクセスによるデータ競合を防止することは最も基本的な要件である。libuvはPOSIXのpthread_mutexとWindowsのCRITICAL_SECTIONの差異を吸収し、統一的なミューテックスAPIを提供する。デバッグビルド時にはERRORCHECK型ミューテックスを使用することで、二重ロックや未所有ロックの解放といったプログラミングエラーの早期発見を支援する。

**機能の利用シーン**：スレッドプール内のワーカースレッド間でのキュー操作の排他制御、イベントループの内部状態保護、ユーザーアプリケーションでの共有データ構造への安全なアクセスに利用される。libuv内部でもwq_mutex（ワークキューミューテックス）として広く使用されている。

**主要な処理内容**：
1. uv_mutex_init()による通常ミューテックスの初期化（デバッグ時ERRORCHECK型）
2. uv_mutex_init_recursive()による再帰ミューテックスの初期化
3. uv_mutex_destroy()によるミューテックスの破棄
4. uv_mutex_lock()によるブロッキングロック取得
5. uv_mutex_trylock()による非ブロッキングロック試行
6. uv_mutex_unlock()によるロック解放

**関連システム・外部連携**：Unix系ではpthread_mutex_*系関数、WindowsではCriticalSection系関数（InitializeCriticalSection、EnterCriticalSection等）をラップする。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 28 | スレッド | 主機能 | uv_mutex_init()/destroy()/lock()/trylock()/unlock()のAPI定義 |
| 36 | スレッド | 補助機能 | ミューテックスによる排他制御のサンプル解説 |

## 機能種別

同期プリミティブ操作（排他制御）

## 入力仕様

### 入力パラメータ

#### uv_mutex_init() / uv_mutex_init_recursive()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | uv_mutex_t* | Yes | 初期化するミューテックスオブジェクト | NULLの場合は未定義動作 |

#### uv_mutex_lock() / uv_mutex_trylock() / uv_mutex_unlock() / uv_mutex_destroy()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | uv_mutex_t* | Yes | 操作対象のミューテックスオブジェクト | NULLの場合は未定義動作 |

### 入力データソース

呼び出し元アプリケーションからの直接指定。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 (init) | int | 成功時0、失敗時負のエラーコード |
| 戻り値 (trylock) | int | 成功時0、ロック取得失敗時UV_EBUSY |
| 戻り値 (lock/unlock/destroy) | void | 失敗時abort()によりプロセス強制終了 |

### 出力先

呼び出し元への戻り値。lock/unlock/destroyは失敗時にプロセスを強制終了する。

## 処理フロー

### 処理シーケンス

```
uv_mutex_init():
1. [Unix/デバッグビルド] ERRORCHECK型属性の設定
   └─ pthread_mutexattr_init() + pthread_mutexattr_settype(PTHREAD_MUTEX_ERRORCHECK)
   └─ pthread_mutex_init(mutex, &attr)
   └─ pthread_mutexattr_destroy()
2. [Unix/リリースビルド] pthread_mutex_init(mutex, NULL)
3. [Windows] InitializeCriticalSection(mutex)

uv_mutex_init_recursive():
1. [Unix] RECURSIVE型属性の設定
   └─ pthread_mutexattr_init() + pthread_mutexattr_settype(PTHREAD_MUTEX_RECURSIVE)
   └─ pthread_mutex_init(mutex, &attr)
2. [Windows] uv_mutex_init()と同一（CRITICAL_SECTIONは再帰的）

uv_mutex_lock():
1. [Unix] pthread_mutex_lock(mutex) → 失敗時abort()
2. [Windows] EnterCriticalSection(mutex)

uv_mutex_trylock():
1. [Unix] pthread_mutex_trylock(mutex)
   └─ 成功: 0を返す
   └─ EBUSY/EAGAIN: UV_EBUSYを返す
   └─ その他エラー: abort()
2. [Windows] TryEnterCriticalSection(mutex)
   └─ 成功: 0を返す
   └─ 失敗: UV_EBUSYを返す

uv_mutex_unlock():
1. [Unix] pthread_mutex_unlock(mutex) → 失敗時abort()
2. [Windows] LeaveCriticalSection(mutex)

uv_mutex_destroy():
1. [Unix] pthread_mutex_destroy(mutex) → 失敗時abort()
2. [Windows] DeleteCriticalSection(mutex)
```

### フローチャート

```mermaid
flowchart TD
    A[uv_mutex_init] --> B{デバッグビルド?}
    B -->|Yes| C[ERRORCHECK属性設定]
    C --> D[pthread_mutex_init with attr]
    B -->|No/Windows| E[pthread_mutex_init NULL / InitializeCriticalSection]
    D --> F[結果返却]
    E --> F

    G[uv_mutex_lock] --> H{プラットフォーム}
    H -->|Unix| I[pthread_mutex_lock]
    I --> J{成功?}
    J -->|Yes| K[return]
    J -->|No| L[abort]
    H -->|Windows| M[EnterCriticalSection]
    M --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-132-01 | デバッグ型ミューテックス | デバッグビルド（NDEBUGなし）かつPTHREAD_MUTEX_ERRORCHECK定義時、ERRORCHECK型で初期化される | Unix/デバッグビルド |
| BR-132-02 | Windows再帰性 | WindowsのCRITICAL_SECTIONは本質的に再帰的であるため、init_recursive()はinit()と同一実装 | Windows |
| BR-132-03 | 致命的エラー | lock/unlock/destroyの失敗はabort()による即時プロセス終了 | 常時 |
| BR-132-04 | trylockのEBUSY | ロック取得に失敗した場合、EBUSY/EAGAINをUV_EBUSYに変換して返す | trylock失敗時 |

### 計算ロジック

特になし。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EBUSY | ロック競合 | trylock()でロックが既に他スレッドに保持されている | リトライまたは別の処理を行う |
| abort() | 致命的エラー | lock/unlock/destroyでの内部エラー | プログラムのロジックを修正する |

### リトライ仕様

trylock()がUV_EBUSYを返した場合、呼び出し元でリトライロジックを実装可能。lock()はブロッキングで待機するためリトライ不要。

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

該当なし。

## パフォーマンス要件

ミューテックスのlock/unlockはカーネルモード遷移を伴う可能性があるが、非競合時にはユーザースペースで完結する（futexまたはCRITICAL_SECTION）。高スループットが必要な場合はtrylock()によるスピンロックパターンの使用を検討する。

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

ミューテックスのデッドロックはサービス停止につながるため、ロック順序の統一や適切なタイムアウト設計が必要。

## 備考

- Unix版のデバッグビルドではERRORCHECK型ミューテックスを使用するため、同一スレッドによる二重ロックやロック未保持での解放が検出可能となる。
- WindowsのCRITICAL_SECTIONは本質的に再帰的であるため、uv_mutex_init_recursive()はuv_mutex_init()への直接的な委譲となっている。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | unix.h | `include/uv/unix.h` | uv_mutex_tの型定義（L131: pthread_mutex_tのtypedef） |
| 1-2 | win.h | `include/uv/win.h` | uv_mutex_tの型定義（L240: CRITICAL_SECTIONのtypedef） |
| 1-3 | uv.h | `include/uv.h` | API宣言（L1847-1852） |

**読解のコツ**: uv_mutex_tはUnixではpthread_mutex_t、WindowsではCRITICAL_SECTIONの直接的なtypedefであり、追加のラッパー構造体は存在しない。

#### Step 2: Unix版実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | thread.c (Unix) | `src/unix/thread.c` | uv_mutex_init()（L316-336）のデバッグ/リリース分岐 |
| 2-2 | thread.c (Unix) | `src/unix/thread.c` | uv_mutex_init_recursive()（L339-355）のRECURSIVE属性設定 |
| 2-3 | thread.c (Unix) | `src/unix/thread.c` | uv_mutex_destroy/lock/trylock/unlock（L358-387） |

**主要処理フロー**:
- **L316-336 (init)**: NDEBUGなしかつPTHREAD_MUTEX_ERRORCHECK定義時はERRORCHECK型、それ以外はデフォルト
- **L339-355 (init_recursive)**: PTHREAD_MUTEX_RECURSIVE属性を設定
- **L358-361 (destroy)**: pthread_mutex_destroy失敗でabort()
- **L364-367 (lock)**: pthread_mutex_lock失敗でabort()
- **L370-381 (trylock)**: EBUSY/EAGAINならUV_EBUSY、それ以外はabort()
- **L384-387 (unlock)**: pthread_mutex_unlock失敗でabort()

#### Step 3: Windows版実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | thread.c (Win) | `src/win/thread.c` | uv_mutex_init()（L370-373）: InitializeCriticalSection |
| 3-2 | thread.c (Win) | `src/win/thread.c` | uv_mutex_init_recursive()（L376-378）: uv_mutex_init()への委譲 |
| 3-3 | thread.c (Win) | `src/win/thread.c` | destroy/lock/trylock/unlock（L381-401） |

**主要処理フロー**:
- **L370-373 (init)**: InitializeCriticalSection、常に0を返す
- **L376-378 (init_recursive)**: uv_mutex_init()を呼ぶだけ（CriticalSectionは本質的に再帰的）
- **L381-383 (destroy)**: DeleteCriticalSection
- **L386-388 (lock)**: EnterCriticalSection
- **L391-396 (trylock)**: TryEnterCriticalSection、失敗時UV_EBUSY
- **L399-401 (unlock)**: LeaveCriticalSection

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

```
uv_mutex_init(handle)
    |
    +-- [Unix/Debug] pthread_mutexattr_init()
    |                pthread_mutexattr_settype(ERRORCHECK)
    |                pthread_mutex_init(mutex, &attr)
    |                pthread_mutexattr_destroy()
    +-- [Unix/Release] pthread_mutex_init(mutex, NULL)
    +-- [Windows] InitializeCriticalSection(mutex)

uv_mutex_lock(handle)
    +-- [Unix] pthread_mutex_lock(mutex) → 失敗: abort()
    +-- [Windows] EnterCriticalSection(mutex)

uv_mutex_trylock(handle)
    +-- [Unix] pthread_mutex_trylock(mutex)
    |         → EBUSY/EAGAIN: UV_EBUSY
    |         → その他エラー: abort()
    +-- [Windows] TryEnterCriticalSection(mutex)
              → FALSE: UV_EBUSY
```

### データフロー図

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

uv_mutex_t* handle --> pthread_mutex_init()   --> 初期化済みミューテックス
                       / InitializeCriticalSection()

uv_mutex_t* handle --> pthread_mutex_lock()   --> ロック取得（ブロッキング）
                       / EnterCriticalSection()

uv_mutex_t* handle --> pthread_mutex_trylock() --> 0（成功）/ UV_EBUSY（競合）
                       / TryEnterCriticalSection()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | API宣言（L1847-1852） |
| unix.h | `include/uv/unix.h` | ヘッダ | uv_mutex_t型定義（L131） |
| win.h | `include/uv/win.h` | ヘッダ | uv_mutex_t型定義（L240） |
| thread.c (Unix) | `src/unix/thread.c` | ソース | Unix版ミューテックス実装（L316-387） |
| thread.c (Win) | `src/win/thread.c` | ソース | Windows版ミューテックス実装（L370-401） |
