# 機能設計書 82-タイマー再開

## 概要

本ドキュメントは、libuvにおけるタイマー再開機能（uv_timer_again）の設計仕様を記述する。uv_timer_again()はリピート設定のあるタイマーを停止して再開し、リピート間隔をタイムアウト値として再スタートさせる。

### 本機能の処理概要

**業務上の目的・背景**：繰り返し実行されるタイマーにおいて、次の発火タイミングをリセットしたい場合がある。例えばアイドル検出タイマーのように、ユーザーアクティビティがあるたびにタイマーを再開始して、一定時間の無操作を検出する用途である。uv_timer_again()はこのようなパターンを簡潔に実現する。

**機能の利用シーン**：アイドル検出（ユーザー操作のたびにタイマーリセット）、ウォッチドッグタイマーのリセット、定期ポーリング間隔の再設定、コネクション生存確認タイマーのリセットなどで使用される。

**主要な処理内容**：
1. timer_cbがNULLでないことを確認する（初期化済みタイマーの検証）
2. repeat値が0より大きい場合のみ再開処理を実行する
3. uv_timer_stop()で現在のタイマーを停止する
4. uv_timer_start()でrepeat値をtimeoutとrepeatの両方に設定して再開する

**関連システム・外部連携**：libuvのタイマーサブシステム内部で完結する。uv_timer_stop()とuv_timer_start()を内部的に呼び出す。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 9 | タイマー | 主機能 | uv_timer_again()によるリピートタイマー再開のAPI定義 |

## 機能種別

状態制御 / タイマー管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | uv_timer_t* | Yes | 再開対象のタイマーハンドル | timer_cbがNULLの場合UV_EINVALを返す |

### 入力データソース

呼び出し元のアプリケーションコードから直接渡されるタイマーハンドルポインタ。uv_timer_start()で一度開始済みであること（timer_cbが設定済みであること）が前提。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 成功時0、timer_cbがNULLの場合UV_EINVAL |

### 出力先

呼び出し元への戻り値として返却。副作用としてタイマーヒープの更新が行われる。

## 処理フロー

### 処理シーケンス

```
1. コールバック検証
   └─ handle->timer_cbがNULLならUV_EINVALを返す
2. リピート値チェック
   └─ handle->repeatが0より大きいか確認
3. タイマー停止
   └─ uv_timer_stop(handle)で現在のタイマーを停止
4. タイマー再開
   └─ uv_timer_start(handle, handle->timer_cb, handle->repeat, handle->repeat)
5. 戻り値0を返す
```

### フローチャート

```mermaid
flowchart TD
    A[uv_timer_again 呼び出し] --> B{timer_cb == NULL?}
    B -->|Yes| C[return UV_EINVAL]
    B -->|No| D{repeat > 0?}
    D -->|No| E[return 0 何もしない]
    D -->|Yes| F[uv_timer_stop]
    F --> G[uv_timer_start with repeat as timeout]
    G --> E
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-82-01 | コールバック必須 | timer_cbがNULLの場合はUV_EINVALを返す | 常時 |
| BR-82-02 | リピート値依存 | repeat値が0の場合は何もせず成功を返す | repeat == 0の場合 |
| BR-82-03 | タイムアウト値の設定 | 再開時のタイムアウトにはrepeat値が使用される | repeat > 0の場合 |

### 計算ロジック

再開時のタイムアウト計算: `clamped_timeout = loop->time + handle->repeat`（uv_timer_start内で計算）

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | 無効引数 | timer_cbがNULL（一度もuv_timer_startされていない） | 先にuv_timer_start()を呼ぶ |

### リトライ仕様

リトライ不要。

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

トランザクション制御なし。

## パフォーマンス要件

- uv_timer_stop() + uv_timer_start()の合計: O(log n)

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

特になし。

## 備考

- uv__run_timers()内部でタイマー発火後にuv_timer_again()が呼ばれ、リピートタイマーの自動再スタートを実現している。
- repeat値が0のタイマーに対してuv_timer_again()を呼んでも何も起こらず、成功（0）を返す。この場合タイマーはワンショットとして扱われる。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | **971-974行目**: uv_timer_s構造体。timer_cb、timeout、repeatフィールドに注目 |

**読解のコツ**: repeat値が0かどうかでワンショット/リピートの挙動が切り替わることを理解する。

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

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

**主要処理フロー**:
1. **113-114行目**: timer_cbのNULLチェック。NULLならUV_EINVALを返す
2. **116行目**: repeat値が0でないかチェック
3. **117行目**: uv_timer_stop()で停止
4. **118行目**: uv_timer_start()でrepeat値をtimeoutとして再開

#### Step 3: 呼び出し元を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | timer.c | `src/timer.c` | **164-194行目**: uv__run_timers()。**191行目**でuv_timer_again()が呼ばれ、発火後のリピートタイマー再スタートを実現 |

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

```
uv_timer_again(handle)
    |
    +-- [timer_cb == NULL] --> return UV_EINVAL
    |
    +-- [repeat > 0]
    |       |
    |       +-- uv_timer_stop(handle)
    |       |       +-- heap_remove() / uv__handle_stop()
    |       |
    |       +-- uv_timer_start(handle, timer_cb, repeat, repeat)
    |               +-- heap_insert() / uv__handle_start()
    |
    +-- return 0
```

### データフロー図

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

uv_timer_t* ───> uv_timer_again()        ───> int (0 or UV_EINVAL)
  handle            |
                    +-- repeat値を読み取り
                    +-- タイマー停止(stop)
                    +-- タイマー再開(start)
                          timeout = repeat
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | uv_timer_again()のAPI宣言（982行目） |
| timer.c | `src/timer.c` | ソース | uv_timer_again()の実装（112-122行目） |
