# 機能設計書 78-Pollイベント監視開始・停止

## 概要

uv_poll_start()/uv_poll_stop()によりFDのイベント監視を開始・停止する（READABLE/WRITABLE/DISCONNECT/PRIORITIZED）機能の設計書である。

### 本機能の処理概要

uv_poll_start()は指定されたイベントの監視を開始し、イベント発生時にコールバックを呼び出す。uv_poll_stop()は監視を停止する。監視対象のイベントはUV_READABLE、UV_WRITABLE、UV_DISCONNECT、UV_PRIORITIZEDの組み合わせで指定できる。

**業務上の目的・背景**：Pollハンドルを初期化した後、実際のイベント監視を開始するためにuv_poll_start()を呼び出す必要がある。監視中に監視イベントの変更やコールバックの変更が必要な場合、uv_poll_start()を再度呼び出すことで動的に変更できる。監視を一時停止する場合はuv_poll_stop()を使用する。

**機能の利用シーン**：
- ファイルディスクリプタの読み取り可能/書き込み可能イベントの監視
- ソケットの切断検知
- sysfsファイルの優先データ（POLLPRI）監視
- 動的なイベント監視の変更（読み取りのみ -> 読み書き両方など）

**主要な処理内容**：
1. uv_poll_start(): 指定イベントをPOLLIN/POLLOUT等に変換し、I/O watcherを起動する
2. uv_poll_stop(): I/O watcherを停止し、プラットフォームのFD無効化を行う
3. イベント発生時: uv__poll_io()コールバックでPOLL*イベントをUV_*イベントに変換してユーザーコールバックを呼び出す

**関連システム・外部連携**：epoll/kqueue/IOCPバックエンド。

**権限による制御**：対象FDへのアクセス権が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 14 | Pollハンドル | 主機能 | uv_poll_start()/uv_poll_stop()のAPI定義 |

## 機能種別

イベント監視制御 - FDイベントの監視開始・停止

## 入力仕様

### 入力パラメータ

#### uv_poll_start()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | uv_poll_t* | Yes | Pollハンドル | 初期化済みかつクローズ中でないこと |
| events | int | Yes | 監視するイベントの組み合わせ | UV_READABLE/UV_WRITABLE/UV_DISCONNECT/UV_PRIORITIZEDのビットOR |
| cb | uv_poll_cb | Yes | イベント発生時のコールバック | NULLでないこと |

#### uv_poll_stop()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | uv_poll_t* | Yes | Pollハンドル | クローズ中でないこと |

### 入力データソース

関数呼び出し時の引数として渡される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 成功時0、失敗時は負のエラーコード |

### 出力先

I/Oイベント発生時にコールバック関数が呼び出される。

## 処理フロー

### 処理シーケンス

```
uv_poll_start():
1. イベントフラグのバリデーション（assert）
2. クローズ中でないことの確認（assert）
3. FD重複チェック（他のwatcherが同一FDを監視していないか）
4. uv__poll_stop()で既存の監視を停止
5. events == 0の場合はここで終了
6. UV_*イベントをPOLL*イベントに変換
   ├─ UV_READABLE -> POLLIN
   ├─ UV_PRIORITIZED -> UV__POLLPRI
   ├─ UV_WRITABLE -> POLLOUT
   └─ UV_DISCONNECT -> UV__POLLRDHUP
7. uv__io_start()でI/O watcherを起動
8. uv__handle_start()でハンドルをアクティブ化
9. handle->poll_cb = poll_cbを設定

uv_poll_stop():
1. クローズ中でないことの確認（assert）
2. uv__poll_stop()の呼び出し
   ├─ uv__io_stop()でI/O watcherを停止
   ├─ uv__handle_stop()でハンドルを非アクティブ化
   └─ uv__platform_invalidate_fd()でプラットフォーム固有のFD無効化
```

### フローチャート

```mermaid
flowchart TD
    A[uv_poll_start] --> B[assertバリデーション]
    B --> C{FD重複?}
    C -->|Yes| D[return UV_EEXIST]
    C -->|No| E[既存監視停止]
    E --> F{events == 0?}
    F -->|Yes| G[return 0]
    F -->|No| H[UV_* -> POLL*変換]
    H --> I[uv__io_start]
    I --> J[uv__handle_start]
    J --> K[poll_cb設定]
    K --> L[return 0]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-78-01 | 再呼び出し可能 | uv_poll_start()は再度呼び出すことでイベントとコールバックを変更可能 | 常時 |
| BR-78-02 | events=0で停止 | events引数に0を渡すと監視が停止される | events == 0 |
| BR-78-03 | FD重複防止 | 同一FDを異なるwatcherが監視している場合はUV_EEXIST | 他のwatcherが同一FDを使用中 |
| BR-78-04 | POLLERRハンドリング | POLLERR(POLLPRI無し)の場合はUV_EBADFでコールバックを呼び出す | I/Oエラー発生時 |

### 計算ロジック

イベント変換:
- UV_READABLE (1) -> POLLIN
- UV_WRITABLE (2) -> POLLOUT
- UV_DISCONNECT (4) -> UV__POLLRDHUP
- UV_PRIORITIZED (8) -> UV__POLLPRI

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EEXIST | 重複エラー | 同一FDが他のwatcherで監視中 | 他のwatcherを停止してから再開 |
| UV_EBADF | I/Oエラー | POLLERRイベント受信時にコールバックに渡される | FDの状態を確認・再初期化 |

### リトライ仕様

リトライは不要。

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

該当なし。

## パフォーマンス要件

epoll_ctl/kevent操作は軽量である。イベント変換はビット操作で実行される。

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

特段のセキュリティ考慮はない。

## 備考

- POLLERRとPOLLPRIが同時に発生した場合、POLLERRではなくPOLLPRIとして処理される（sysfsポーリング対応）
- Windows版ではWSAEventSelectベースの実装となる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | **L910-915**: uv_poll_event列挙型 |

#### Step 2: イベント監視制御を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | poll.c | `src/unix/poll.c` | **L118-154**: uv_poll_start()の全実装 |
| 2-2 | poll.c | `src/unix/poll.c` | **L111-115**: uv_poll_stop()の実装 |
| 2-3 | poll.c | `src/unix/poll.c` | **L102-108**: uv__poll_stop()内部関数 |

**主要処理フロー (uv_poll_start)**:
1. **123-124行目**: assertでイベントフラグのバリデーション
2. **130-132行目**: FD重複チェック
3. **134行目**: uv__poll_stop()で既存監視停止
4. **136-137行目**: events == 0なら早期リターン
5. **139-147行目**: UV_*からPOLL*へのイベント変換
6. **149行目**: uv__io_start()でwatcher起動
7. **150行目**: uv__handle_start()
8. **151行目**: poll_cb設定

#### Step 3: I/Oコールバックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | poll.c | `src/unix/poll.c` | **L29-64**: uv__poll_io() - POLL*からUV_*への逆変換とコールバック呼び出し |

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

```
uv_poll_start(handle, pevents, poll_cb)   [src/unix/poll.c L118]
    +-- uv__poll_stop(handle)              [既存監視停止]
    |   +-- uv__io_stop()
    |   +-- uv__handle_stop()
    |   +-- uv__platform_invalidate_fd()
    +-- uv__io_start(loop, watcher, events) [監視開始]
    +-- uv__handle_start(handle)

uv_poll_stop(handle)                       [src/unix/poll.c L111]
    +-- uv__poll_stop(handle)              [L102-108]

[イベント発生時]
uv__poll_io(loop, w, events)              [src/unix/poll.c L29]
    +-- POLL* -> UV_* イベント変換
    +-- handle->poll_cb(handle, status, pevents)
```

### データフロー図

```
[入力]                [処理]                        [出力]
pevents (UV_*) -----> UV_* -> POLL* 変換 ---------> epoll/kqueue登録
poll_cb (コールバック) uv__io_start()
                     [イベント発生時]
                     POLL* -> UV_* 逆変換 --------> poll_cb(handle, 0, UV_*)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | API宣言（L921-922）、uv_poll_event定義（L910-915） |
| poll.c | `src/unix/poll.c` | ソース | Unix版実装（L29-160） |
| poll.c | `src/win/poll.c` | ソース | Windows版実装（L514-521） |
