# 機能設計書 173-スリープ

## 概要

本ドキュメントは、libuv の `uv_sleep()` 関数による指定ミリ秒間のスレッドスリープ機能について、その設計仕様を記載する。

### 本機能の処理概要

`uv_sleep()` は、呼び出しスレッドを指定されたミリ秒間スリープ（一時停止）させる関数である。戻り値は void で、指定時間が経過するまでブロックする。

**業務上の目的・背景**：非同期I/Oライブラリであるlibuvにおいて、テスト、ポーリング間隔の調整、起動タイミングの同期など、意図的にスレッドの実行を一時停止させる場面がある。本機能はクロスプラットフォームで統一されたスリープAPIを提供する。POSIX の `sleep()` / `usleep()` / `nanosleep()` や Windows の `Sleep()` といったプラットフォーム固有APIの差異を吸収する。

**機能の利用シーン**：テストにおける待機処理、リトライ間のバックオフ待機、起動時のタイミング調整、レート制限の実装、デバッグ目的の遅延挿入などに利用される。ただし、イベントループスレッドでの使用はループ全体をブロックするため推奨されない。

**主要な処理内容**：
1. ミリ秒をプラットフォーム固有の時間表現に変換
2. プラットフォーム固有のスリープAPIを呼び出し
3. Unix系ではシグナル割り込み（EINTR）時に自動的にリトライ

**関連システム・外部連携**：Unix 系では POSIX の `nanosleep()` を使用し、Windows では Win32 の `Sleep()` を使用する。

**権限による制御**：特別な権限は不要である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | その他ユーティリティ | 主機能 | uv_sleep()による指定ミリ秒スリープのAPI定義 |

## 機能種別

制御処理（スレッド実行の一時停止）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| msec | unsigned int | Yes | スリープするミリ秒数 | 特に制限なし。0を指定した場合の動作はプラットフォーム依存 |

### 入力データソース

呼び出し元からの直接指定。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (なし) | void | 戻り値なし |

### 出力先

なし（副作用として呼び出しスレッドが指定時間停止する）。

## 処理フロー

### 処理シーケンス

```
1. ミリ秒を時間構造体に変換
   └─ Unix: struct timespec に秒（msec/1000）とナノ秒（(msec%1000)*1000*1000）をセット
   └─ Windows: 変換不要（ミリ秒をそのまま使用）
2. スリープAPI呼び出し
   └─ Unix: nanosleep() を呼び出し
   └─ Windows: Sleep() を呼び出し
3. [Unix のみ] EINTR 処理
   └─ nanosleep() が EINTR で中断された場合、残り時間で再度 nanosleep() を呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{プラットフォーム}
    B -->|Unix| C[msec を struct timespec に変換]
    C --> D[nanosleep 呼び出し]
    D --> E{rc == -1 && errno == EINTR?}
    E -->|Yes| D
    E -->|No| F[終了]
    B -->|Windows| G[Sleep msec 呼び出し]
    G --> F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-173-01 | EINTR自動リトライ | UnixでシグナルによりEINTRが発生した場合、残り時間で自動リトライする | Unix版のみ |
| BR-173-02 | ブロッキング動作 | 呼び出しスレッドは指定時間ブロックされる | 常時 |

### 計算ロジック

Unix 系のミリ秒から timespec への変換:
- `timeout.tv_sec = msec / 1000`
- `timeout.tv_nsec = (msec % 1000) * 1000 * 1000`

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

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

該当なし。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| (なし) | - | 関数は void を返すためエラーコードなし | Unix版では内部的に EINTR を自動リトライする |

### リトライ仕様

Unix版では `nanosleep()` がシグナルにより EINTR で中断された場合、残り時間（nanosleepが更新した timeout）を使って自動的にリトライする（do-while ループ、src/unix/core.c L1948-1950）。

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

該当なし。

## パフォーマンス要件

指定されたミリ秒だけスレッドをブロックする。実際のスリープ時間はOSのスケジューリング粒度により若干の誤差が生じる場合がある。

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

特別なセキュリティ要件はない。

## 備考

- イベントループのメインスレッドでこの関数を呼び出すと、ループ全体がブロックされるため注意が必要。
- Windows版は `Sleep(msec)` を直接呼び出す1行の実装である。
- Unix版はアサーション `assert(rc == 0)` により、EINTR以外のエラーが発生した場合はアボートする。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | API宣言（1838行目）: `void uv_sleep(unsigned int msec)` |

**読解のコツ**: 本関数はデータ構造を持たない単純なAPI。unsigned int のミリ秒値を受け取り void を返す。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | core.c | `src/unix/core.c` | Unix版の `uv_sleep()` 実装（1941-1953行目） |

**主要処理フロー**:
- **1942行目**: `struct timespec timeout` をローカル変数として宣言
- **1945-1946行目**: ミリ秒を秒とナノ秒に変換して timespec に格納
- **1948-1950行目**: do-while ループで `nanosleep()` を呼び出し、EINTR の場合は残り時間でリトライ
- **1952行目**: `assert(rc == 0)` でEINTR以外のエラーをアサーション

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | util.c | `src/win/util.c` | Windows版の `uv_sleep()` 実装（1758-1759行目） |

**主要処理フロー**:
- **1759行目**: `Sleep(msec)` を直接呼び出す1行の実装

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

```
uv_sleep(msec)
    |
    +-- [Unix]
    |   +-- nanosleep(&timeout, &timeout)  [EINTR時リトライ]
    |
    +-- [Windows]
        +-- Sleep(msec)
```

### データフロー図

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

msec ──────▶ uv_sleep() ──────▶ (なし: voidを返す)
(unsigned int)   |
                 +-- OS スリープAPI
                 +-- スレッド一時停止
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言 |
| core.c | `src/unix/core.c` | ソース | Unix版の uv_sleep() 実装 |
| util.c | `src/win/util.c` | ソース | Windows版の uv_sleep() 実装 |
