# 機能設計書 81-タイマー停止

## 概要

本ドキュメントは、libuvにおけるタイマー停止機能（uv_timer_stop）の設計仕様を記述する。uv_timer_stop()は実行中のタイマーハンドルを停止し、タイマーヒープから除去することで、予定されていたコールバックの発火を取り消す。

### 本機能の処理概要

**業務上の目的・背景**：イベント駆動プログラミングにおいて、タイマーは非同期処理のスケジューリングに不可欠な要素である。しかし、条件変化やユーザー操作によって予定されていたタイマーイベントを取り消す必要が生じる場面は多い。uv_timer_stop()はこの要求に応え、登録済みタイマーを安全に停止する手段を提供する。不要なタイマーを放置するとメモリリークやイベントループの不要な継続が発生するため、適切な停止処理は重要である。

**機能の利用シーン**：タイムアウト処理において接続が成功した際のタイマー取り消し、リピートタイマーの動的な停止、ハンドルクローズ前の前処理としてのタイマー停止、アプリケーション終了前のリソースクリーンアップなどで使用される。

**主要な処理内容**：
1. ハンドルがアクティブかどうかを判定する
2. アクティブな場合、タイマーヒープ（最小ヒープ）からハンドルのノードを除去する
3. uv__handle_stop()でハンドルのアクティブフラグを解除し、ループのアクティブハンドル数をデクリメントする
4. 非アクティブの場合、キューからノードを除去する
5. キューノードを再初期化する

**関連システム・外部連携**：libuvのイベントループサブシステム（タイマーヒープ管理）と連携する。OSレベルの外部システムとの直接連携はない。

**権限による制御**：特に権限制御はない。任意のスレッドから呼び出し可能だが、ハンドルを所有するイベントループスレッドからの呼び出しが前提となる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 9 | タイマー | 主機能 | uv_timer_stop()によるタイマー停止のAPI定義 |

## 機能種別

リソース制御 / 状態管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | uv_timer_t* | Yes | 停止対象のタイマーハンドル | NULLであってはならない（明示的チェックはないが前提条件） |

### 入力データソース

呼び出し元のアプリケーションコードから直接渡されるタイマーハンドルポインタ。uv_timer_init()で初期化済みのハンドルであることが前提。

## 出力仕様

### 出力データ

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

### 出力先

呼び出し元への戻り値として返却。副作用としてタイマーヒープからの除去とハンドル状態の更新が行われる。

## 処理フロー

### 処理シーケンス

```
1. アクティブ状態判定
   └─ uv__is_active(handle)でハンドルがアクティブかチェック
2a. アクティブの場合: ヒープからの除去
   ├─ heap_remove()でタイマーヒープからノードを除去
   └─ uv__handle_stop()でハンドルを非アクティブ化
2b. 非アクティブの場合: キューからの除去
   └─ uv__queue_remove()でキューからノードを除去
3. キューノード再初期化
   └─ uv__queue_init()でキューノードを自己参照状態にリセット
4. 戻り値0を返す
```

### フローチャート

```mermaid
flowchart TD
    A[uv_timer_stop 呼び出し] --> B{uv__is_active?}
    B -->|Yes| C[heap_remove: タイマーヒープから除去]
    C --> D[uv__handle_stop: ハンドル非アクティブ化]
    D --> E[uv__queue_init: キューノード再初期化]
    B -->|No| F[uv__queue_remove: キューから除去]
    F --> E
    E --> G[return 0]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-81-01 | 冪等性保証 | 既に停止しているタイマーに対してuv_timer_stop()を呼んでもエラーにならない | 常時 |
| BR-81-02 | アクティブハンドル数管理 | 停止時にループのアクティブハンドル数がデクリメントされる | ハンドルがアクティブな場合のみ |
| BR-81-03 | ヒープ整合性維持 | heap_remove()呼び出し時にtimer_less_than比較関数を使用してヒープ整合性を維持する | ハンドルがアクティブな場合 |

### 計算ロジック

特になし。

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

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

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

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| なし | - | uv_timer_stop()は常に0を返す | - |

### リトライ仕様

リトライ不要。常に成功する。

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

トランザクション制御なし。タイマーヒープへの操作はアトミックに行われるが、マルチスレッド同期は呼び出し側の責務。

## パフォーマンス要件

- ヒープ除去操作の計算量: O(log n)（nはタイマーヒープ内の要素数）
- 非アクティブ時のキュー除去: O(1)

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

特になし。ユーザー空間のメモリ操作のみで、特権操作は含まない。

## 備考

- uv_timer_stop()はuv_timer_start()の内部でも呼ばれ、タイマーの再設定時に既存のタイマーを停止する用途でも使用される。
- uv__timer_close()内部でもuv_timer_stop()が呼ばれ、ハンドルクローズ時のクリーンアップとして機能する。
- uv__run_timers()内部でも、発火したタイマーの停止のためにuv_timer_stop()が呼ばれる。

---

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

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

### 推奨読解順序

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

タイマーハンドルとタイマーヒープの構造体を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | **971-974行目**: uv_timer_s構造体。UV_HANDLE_FIELDSとUV_TIMER_PRIVATE_FIELDSで構成される |
| 1-2 | heap-inl.h | `src/heap-inl.h` | **27-31行目**: heap_node構造体（left/right/parent）。**40-43行目**: heap構造体（min/nelts） |

**読解のコツ**: uv_timer_tのnode.heapフィールドがヒープノードとして使われ、node.queueフィールドが発火待ちキューとして使われる。container_ofマクロでノードから親構造体を逆引きする。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | timer.c | `src/timer.c` | **97-109行目**: uv_timer_stop()関数の実装 |

**主要処理フロー**:
1. **98行目**: uv__is_active(handle)でアクティブ判定
2. **99-101行目**: アクティブなら heap_remove() でヒープから除去
3. **102行目**: uv__handle_stop(handle)でハンドル非アクティブ化
4. **104行目**: 非アクティブなら uv__queue_remove()でキューから除去
5. **107行目**: uv__queue_init()でキューノードを再初期化

#### Step 3: ヒープ操作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | heap-inl.h | `src/heap-inl.h` | **150-237行目**: heap_remove()の実装。最後のノードと入れ替えてからヒープ性質を修復する |
| 3-2 | timer.c | `src/timer.c` | **37-54行目**: timer_less_than()比較関数。timeoutで比較し、同じならstart_idで比較 |

**主要処理フロー**:
- **160-161行目**: ヒープが空なら何もしない
- **166-179行目**: 最後のノードへのパスを計算
- **196-214行目**: 削除ノードを最後のノードで置き換え
- **220-236行目**: ヒープ性質の修復（下方向・上方向）

#### Step 4: 関連する内部呼び出しを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | timer.c | `src/timer.c` | **197-199行目**: uv__timer_close()内でuv_timer_stop()が呼ばれる |
| 4-2 | timer.c | `src/timer.c` | **76行目**: uv_timer_start()内でまずuv_timer_stop()が呼ばれる（再設定時の安全性確保） |
| 4-3 | timer.c | `src/timer.c` | **181行目**: uv__run_timers()内で発火済みタイマーのuv_timer_stop()が呼ばれる |

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

```
uv_timer_stop(handle)
    |
    +-- [アクティブの場合]
    |       |
    |       +-- heap_remove(timer_heap, &handle->node.heap, timer_less_than)
    |       |       +-- heap_node_swap()  [ヒープ修復時]
    |       |
    |       +-- uv__handle_stop(handle)
    |               +-- loop->active_handles--
    |
    +-- [非アクティブの場合]
    |       |
    |       +-- uv__queue_remove(&handle->node.queue)
    |
    +-- uv__queue_init(&handle->node.queue)
```

### データフロー図

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

uv_timer_t* ───> uv_timer_stop()         ───> int (0)
  handle            |
                    +-- タイマーヒープ操作
                    |     (heap_remove)
                    +-- ハンドル状態更新
                    |     (flags &= ~ACTIVE)
                    +-- アクティブ数更新
                          (active_handles--)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | uv_timer_stop()のAPI宣言（981行目）、uv_timer_t構造体定義 |
| timer.c | `src/timer.c` | ソース | uv_timer_stop()の実装（97-109行目） |
| heap-inl.h | `src/heap-inl.h` | ヘッダ（インライン） | heap_remove()等のヒープ操作実装 |
| uv-common.h | `src/uv-common.h` | ヘッダ | uv__handle_stop()、uv__is_active()マクロ定義 |
