# 機能設計書 95-シグナル監視停止

## 概要

本ドキュメントは、libuvにおけるシグナル監視停止機能（uv_signal_stop()）の設計を記述する。シグナルの監視を停止し、OSシグナルハンドラの登録解除を行う。

### 本機能の処理概要

**業務上の目的・背景**：シグナル監視が不要になった場合、リソースの適切な解放とOSシグナルハンドラの整理が必要である。uv_signal_stop()は、RBツリーからハンドルを除去し、同一シグナルを監視する他のハンドルがない場合はOSのシグナルハンドラをデフォルトに戻す。

**機能の利用シーン**：アプリケーション終了前のシグナル監視解除、シグナル監視の動的な切り替え、ハンドルクローズ前の後処理として利用される。

**主要な処理内容**：
1. ハンドルがクローズ中でないことを検証
2. 内部のuv__signal_stop()を呼び出して実際の停止処理を実行
3. RBツリーからハンドルを除去
4. 同一シグナルの他のウォッチャーがなければOSハンドラを解除
5. ハンドルを非アクティブ状態にする

**関連システム・外部連携**：POSIX sigaction()（SIG_DFLへのリセット）、グローバルシグナルRBツリーと連携する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 15 | シグナル | 主機能 | uv_signal_stop()によるシグナル監視停止のAPI定義 |

## 機能種別

イベント監視制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | uv_signal_t* | Yes | 停止するシグナルハンドル | NULLでないこと、クローズ中でないこと |

### 入力データソース

呼び出し元コードから直接パラメータとして渡される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 常に0を返す |

### 出力先

呼び出し元への戻り値。

## 処理フロー

### 処理シーケンス

```
1. クローズ中でないことをassertで検証
2. uv__signal_stop(handle) を呼び出す
   ├─ handle->signum == 0 なら何もしない（未開始のため）
   ├─ シグナルブロック+グローバルロック取得
   ├─ RBツリーからハンドルを除去
   ├─ 同一シグナルの最初のハンドルを検索
   │   ├─ なし: OSシグナルハンドラを解除（SIG_DFLに戻す）
   │   └─ あり + ワンショットのみ残った: ハンドラを再登録（SA_RESETHAND付き）
   ├─ ロック解放+シグナル復帰
   ├─ handle->signum = 0
   └─ uv__handle_stop(handle)
3. 0 を返す
```

### フローチャート

```mermaid
flowchart TD
    A[uv_signal_stop 呼び出し] --> B{signum == 0?}
    B -->|Yes| C[何もしない - 0 返却]
    B -->|No| D[グローバルロック取得]
    D --> E[RBツリーからハンドル除去]
    E --> F{同一signum の他ハンドル?}
    F -->|なし| G[OSハンドラ解除 - SIG_DFL]
    F -->|あり| H{ワンショットのみ残った?}
    H -->|Yes| I[ハンドラ再登録 - SA_RESETHAND付き]
    H -->|No| J[ロック解放]
    G --> J
    I --> J
    J --> K[signum=0, handle停止]
    K --> L[0 返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-95-1 | 未開始の停止は無操作 | signum==0の場合は何もせずに返る | 未開始のハンドル |
| BR-95-2 | OSハンドラ解除条件 | 同一シグナルの他のウォッチャーがない場合のみOSハンドラを解除 | 最後のウォッチャー停止時 |
| BR-95-3 | ワンショット残留時の再登録 | 通常ハンドラが除去されワンショットのみ残った場合、SA_RESETHANDでハンドラを再登録 | 該当条件発生時 |
| BR-95-4 | signumリセット | 停止後にhandle->signumを0にリセット | 常時 |

### 計算ロジック

特になし。

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

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 本関数は常に0を返す | - |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

同期的な処理であり、マイクロ秒オーダーで完了する。

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

- グローバルロック取得中の処理のため、他スレッドとの競合は発生しない

## 備考

- uv_signal_stop()は常に0を返す（エラーなし）
- uv__signal_close()からも呼ばれ、ハンドルクローズ時の後処理としても機能する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | **1720-1725行目**: uv_signal_s構造体 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | signal.c | `src/unix/signal.c` | **533-537行目**: uv_signal_stop()。assertチェック後にuv__signal_stop()を呼び出す |

**主要処理フロー**:
- **534行目**: `assert(!uv__is_closing(handle))` - クローズ中でないことの検証
- **535行目**: `uv__signal_stop(handle)` - 内部停止関数の呼び出し
- **536行目**: `return 0` - 常に成功

#### Step 3: 内部停止処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | signal.c | `src/unix/signal.c` | **540-578行目**: uv__signal_stop()の実装 |

**主要処理フロー**:
- **549-550行目**: signum==0なら即座にreturn
- **552行目**: `uv__signal_block_and_lock()` - シグナルブロック+ロック
- **554行目**: `RB_REMOVE()` - RBツリーからの除去
- **561-572行目**: 残りのハンドル確認とOSハンドラの解除/再登録
- **576行目**: `handle->signum = 0` - signumリセット
- **577行目**: `uv__handle_stop(handle)` - ハンドル非アクティブ化

#### Step 4: OSハンドラ解除を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | signal.c | `src/unix/signal.c` | **244-257行目**: uv__signal_unregister_handler()。SIG_DFLへの復帰 |

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

```
uv_signal_stop(handle)
    |
    +-- uv__signal_stop(handle)
            |
            +-- uv__signal_block_and_lock(&saved_sigmask)
            |
            +-- RB_REMOVE(uv__signal_tree_s, &uv__signal_tree, handle)
            |
            +-- uv__signal_first_handle(handle->signum)
            |
            +-- uv__signal_unregister_handler(signum)  [他ハンドルなしの場合]
            |       |
            |       +-- sigaction(signum, &sa_default, NULL)
            |
            +-- uv__signal_unlock_and_unblock(&saved_sigmask)
            |
            +-- uv__handle_stop(handle)
```

### データフロー図

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

uv_signal_t*   ---> RBツリー除去        --->
                    OSハンドラ解除       ---> OSシグナルテーブル更新
                    ハンドル非アクティブ化 ---> int (0)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | API宣言 |
| signal.c | `src/unix/signal.c` | ソース | Unix系シグナル処理の実装 |
| signal.c | `src/win/signal.c` | ソース | Windowsシグナル処理実装 |
