# 機能設計書 94-WaitHandle

## 概要

本ドキュメントは、VBCorLibライブラリにおけるWaitHandle機能の設計を記述するものである。WaitHandleは、共有リソースへの排他的アクセスを待機するオペレーティングシステム固有のオブジェクトを表すクラスである。

### 本機能の処理概要

WaitHandleは、Windows同期オブジェクト（イベント、ミューテックス、セマフォなど）のハンドルをラップする抽象基底クラスである。シグナル状態を待機するための共通インターフェースを提供する。

**業務上の目的・背景**：マルチプロセス環境やプロセス間通信において、リソースの同期やイベント通知が必要である。WaitHandleクラスは、Windows同期プリミティブを.NET互換のインターフェースで使用可能にする。

**機能の利用シーン**：プロセス間同期、名前付きイベントによる通知、リソースへの排他アクセス制御、タイムアウト付き待機処理に使用される。

**主要な処理内容**：
1. 単一ハンドルの待機（WaitOne）- 指定したハンドルがシグナル状態になるまで待機
2. 複数ハンドルのいずれかの待機（WaitAny）- いずれかのハンドルがシグナル状態になるまで待機
3. 複数ハンドルのすべての待機（WaitAll）- すべてのハンドルがシグナル状態になるまで待機
4. ハンドルの解放（CloseHandle）- ハンドルを閉じてリソースを解放

**関連システム・外部連携**：Windows API（WaitForSingleObject、WaitForMultipleObjects、CloseHandle）を使用。

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに直接の関連なし |

## 機能種別

同期制御 / リソース管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| MillisecondsTimeout | Long | No | 待機タイムアウト（ミリ秒）（デフォルト: INFINITE） | -1（INFINITE）または0以上 |
| WaitHandles | WaitHandle() | Yes（WaitAny/WaitAll） | 待機対象のハンドル配列 | Null禁止、0件禁止、64件以内 |
| ExitContext | Boolean | No | 同期ドメインを終了するか（未実装、常にFalse） | - |

### 入力データソース

- 派生クラス（Mutex、AutoResetEvent等）からのハンドル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| WaitOne戻り値 | Boolean | シグナル状態になった場合True、タイムアウト時False |
| WaitAny戻り値 | Long | シグナル状態になったハンドルのインデックス |
| WaitAll戻り値 | Boolean | すべてがシグナル状態になった場合True |
| InvalidHandle定数 | Long | 無効ハンドル値（-1） |

### 出力先

- 呼び出し元への戻り値

## 処理フロー

### 処理シーケンス

```
1. WaitOne呼び出し
   └─ WaitForSingleObject APIで単一ハンドルを待機
   └─ WAIT_OBJECT_0なら True、WAIT_TIMEOUT なら False

2. WaitAny呼び出し
   └─ ハンドル配列からWindows APIハンドルを抽出
   └─ WaitForMultipleObjects APIで待機
   └─ シグナル状態になったインデックスを返却

3. WaitAll呼び出し
   └─ ハンドル配列からWindows APIハンドルを抽出
   └─ WaitForMultipleObjects APIで待機（WaitAll=True）
   └─ すべてシグナル状態ならTrue

4. CloseHandle呼び出し
   └─ Windows API CloseHandleでハンドルを閉じる
   └─ 内部ハンドルをINVALID_HANDLEに設定
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{操作種別}
    B -->|WaitOne| C[WaitForSingleObject]
    B -->|WaitAny| D[WaitForMultipleObjects]
    B -->|WaitAll| E[WaitForMultipleObjects WaitAll=True]
    C --> F{戻り値}
    F -->|WAIT_OBJECT_0| G[True返却]
    F -->|WAIT_TIMEOUT| H[False返却]
    F -->|WAIT_FAILED| I[Win32Error例外]
    D --> J[シグナルインデックス計算]
    J --> K[インデックス返却]
    E --> L{全シグナル?}
    L -->|Yes| M[True返却]
    L -->|No| N[False返却]
    G --> O[終了]
    H --> O
    I --> O
    K --> O
    M --> O
    N --> O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-94-01 | ハンドル上限 | WaitAny/WaitAllは最大64ハンドルまで | 配列長チェック時 |
| BR-94-02 | Null禁止 | WaitHandles配列にNothingは不可 | WaitAny/WaitAll呼び出し時 |
| BR-94-03 | 空配列禁止 | WaitHandles配列は1件以上必要 | WaitAny/WaitAll呼び出し時 |
| BR-94-04 | INFINITE待機 | MillisecondsTimeout=-1で無限待機 | デフォルト動作 |

### 計算ロジック

```
WaitAnyの戻り値 = APIリターン値 - WAIT_OBJECT_0
（配列の0始まりインデックスに変換）
```

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

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

該当なし

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ArgumentNull | ArgumentNullException | WaitHandles配列がNothing | 有効な配列を渡す |
| Argument_EmptyWaithandleArray | ArgumentException | 空の配列を渡した | 1件以上のハンドルを含める |
| NotSupported_MaxWaitHandles | NotSupportedException | 64件を超えるハンドル | 64件以下に分割 |
| Win32Error | Win32Exception | APIがWAIT_FAILEDを返した | エラーコードを確認 |

### リトライ仕様

特になし

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

該当なし

## パフォーマンス要件

- WaitOne/WaitAny/WaitAllはブロッキング呼び出し
- タイムアウト値0で即時チェック（ノンブロッキング）が可能

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

- 名前付き同期オブジェクトはプロセス間で共有されるため、名前の衝突に注意
- 適切な権限がない場合、システム同期オブジェクトにアクセスできない場合がある

## 備考

- WaitHandleは抽象クラスであり、直接インスタンス化しない
- 派生クラス：Mutex、AutoResetEvent、ManualResetEvent、Semaphore
- .NET FrameworkのSystem.Threading.WaitHandleクラスに対応

---

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

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

### 推奨読解順序

#### Step 1: 定数とエントリーポイントを理解する

WaitHandleクラスの定数と主要メソッドを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | WaitHandle.cls | `Source/CorLib/System.Threading/WaitHandle.cls` | InvalidHandle定数（51行目）とWaitTimeout定数（57行目）を確認 |

**読解のコツ**: WaitTimeout = &H102はWindows APIのWAIT_TIMEOUTに対応する。

#### Step 2: 待機メソッドを理解する

WaitOne、WaitAny、WaitAllの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | WaitHandle.cls | `Source/CorLib/System.Threading/WaitHandle.cls` | WaitOne（68-78行目）で単一ハンドル待機 |
| 2-2 | WaitHandle.cls | `Source/CorLib/System.Threading/WaitHandle.cls` | WaitAny（100-116行目）で複数ハンドルのいずれかを待機 |
| 2-3 | WaitHandle.cls | `Source/CorLib/System.Threading/WaitHandle.cls` | WaitAll（128-144行目）で複数ハンドルの全待機 |

**主要処理フロー**:
- **68-78行目**: WaitOne - WaitForSingleObject APIを呼び出し、WAIT_OBJECT_0ならTrue
- **100-116行目**: WaitAny - GetWaitHandlePointersでハンドル配列を取得、WaitForMultipleObjectsで待機
- **128-144行目**: WaitAll - 同様にWaitForMultipleObjectsを呼び出すが、bWaitAll=Trueを渡す

#### Step 3: ヘルパーメソッドを理解する

ハンドル配列の変換とクローズ処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | WaitHandle.cls | `Source/CorLib/System.Threading/WaitHandle.cls` | GetWaitHandlePointers（161-181行目）でハンドル配列を変換 |
| 3-2 | WaitHandle.cls | `Source/CorLib/System.Threading/WaitHandle.cls` | CloseHandle（80-82行目）でハンドルを閉じる |

**主要処理フロー**:
- **161-181行目**: GetWaitHandlePointers - WaitHandle配列からLong配列（ハンドル値）に変換、バリデーション付き
- **80-82行目**: CloseHandle - 派生クラスで実装される仮想メソッド

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

```
WaitHandle.WaitOne
    │
    └─ WaitForSingleObject（Windows API）
           │
           └─ 戻り値判定
                  ├─ WAIT_OBJECT_0 → True
                  ├─ WAIT_TIMEOUT → False
                  └─ WAIT_FAILED → Win32Error

WaitHandle.WaitAny
    │
    ├─ GetWaitHandlePointers
    │      ├─ 配列バリデーション
    │      └─ ハンドル値抽出
    │
    └─ WaitForMultipleObjects（Windows API）
           │
           └─ 戻り値からインデックス計算

WaitHandle.WaitAll
    │
    ├─ GetWaitHandlePointers
    │
    └─ WaitForMultipleObjects（Windows API, bWaitAll=True）
           │
           └─ 戻り値判定 → Boolean
```

### データフロー図

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

MillisecondsTimeout ────▶ WaitHandle.WaitOne ──────────▶ Boolean（成功/タイムアウト）
Handle ──────────────────┘       │
                                 ▼
                         WaitForSingleObject API

WaitHandle() ────────────▶ WaitHandle.WaitAny ──────────▶ Long（インデックス）
MillisecondsTimeout ────┘       │
                                ▼
                         GetWaitHandlePointers
                                │
                                ▼
                         WaitForMultipleObjects API
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| WaitHandle.cls | `Source/CorLib/System.Threading/WaitHandle.cls` | ソース | 同期待機ハンドルの抽象基底クラス |
