# 画面設計書 39-ユーティリティ

## 概要

libuvユーザーガイドのユーティリティページ（guide/utilities.rst）に関する画面設計書。タイマー、イベントループ参照カウント、Idleパターン、ワーカースレッドへのデータ渡し、外部I/Oポーリング、動的ライブラリ読み込み、TTY制御の使い方をサンプルコード付きで解説するページの構造と仕様を定義する。

### 本画面の処理概要

本ページはlibuvの各種ユーティリティ機能を集約した、最も内容が豊富なガイドページである。タイマーの基本使用法から、参照カウントによるループ存続制御、Idleハンドルの活用パターン、batonパターンによるワーカーへのデータ渡し、libcurlと連携した外部I/Oポーリング（uvwget）、動的ライブラリのプラグインシステム、TTYによるターミナル制御まで、幅広いトピックをカバーする。

**業務上の目的・背景**：libuvはI/Oループの核となる機能以外にも、多くのユーティリティ機能を提供している。本ページではそれらを一つのページに集約し、個別のガイドページを作るほどではないが重要な機能群を解説する。特にuvwgetサンプルはlibcurlとの連携を通じて、サードパーティライブラリとlibuvの統合パターンを示す実践的な例である。TTYセクションではANSIエスケープコードのクロスプラットフォーム抽象化を解説する。

**画面へのアクセス方法**：ユーザーガイド一覧（No.31）のtoctreeリンク、またはイベントループ応用（No.38）からのNextナビゲーションでアクセスする。URLパスは `/guide/utilities.html` となる。

**主要な操作・処理内容**：
1. タイマー（uv_timer_t）の基本使用法と設定変更の説明
2. イベントループ参照カウント（uv_ref/uv_unref）のサンプル（ref-timer/main.c）と解説
3. Idlerパターン（idle-compute/main.c）の表示と解説
4. batonパターンによるワーカーへのデータ渡しの説明
5. 外部I/Oポーリング（uvwget/main.c）-- libcurl連携の表示と解説
6. Check & Prepareウォッチャー（TODOとして未完成）
7. 動的ライブラリ読み込み（plugin/main.c + plugin/hello.c）の表示と解説
8. TTY制御（tty/main.c + tty-gravity/main.c）の表示と解説

**画面遷移**：
- 遷移元：ユーザーガイド一覧（No.31）、イベントループ応用（No.38）
- 遷移先：このプロジェクトについて（No.40）
- 内部参照：`_reference-count` ラベル、`_baton` ラベル
- 外部リンク：libcurl、ncurses、libev manページ

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 79 | タイマー初期化 | 主機能 | タイマーのサンプルコードを用いた使い方の解説 |
| 80 | タイマー開始 | 主機能 | タイマー開始とコールバック処理の使用例 |
| 87 | Idle初期化・開始・停止 | 補助機能 | アイドルハンドルのサンプルコード解説 |

## 画面種別

チュートリアル（サンプルコード付き解説）

## URL/ルーティング

- ソースファイル：`docs/src/guide/utilities.rst`
- 生成先URL：`/guide/utilities.html`
- Sphinxルーティング：guide.rstのtoctreeから参照

## 入出力項目

| 項目名 | 入出力 | 型 | 説明 |
|--------|--------|-----|------|
| タイマー使用法 | 出力 | テキスト/コードブロック | uv_timer_init/start/stop/set_repeat/again |
| ref-timer/main.cコード | 出力 | Cソースコード | 参照カウントサンプル（部分表示、ハイライト付き） |
| idle-compute/main.cコード | 出力 | Cソースコード | Idlerパターンサンプル（部分表示、ハイライト付き） |
| batonパターンコード | 出力 | Cコードブロック | ftp_baton構造体とuv_queue_work使用例 |
| uvwget/main.cコード | 出力 | Cソースコード | libcurl連携サンプル（部分表示、ハイライト付き） |
| plugin/plugin.hコード | 出力 | Cソースコード | プラグインインターフェース定義 |
| plugin/hello.cコード | 出力 | Cソースコード | サンプルプラグイン |
| plugin/main.cコード | 出力 | Cソースコード | プラグイン読み込みプログラム |
| tty/main.cコード | 出力 | Cソースコード | TTY基本サンプル（ハイライト付き） |
| tty-gravity/main.cコード | 出力 | Cソースコード | TTYアニメーションサンプル（ハイライト付き） |
| エスケープコード表 | 出力 | テーブル | ANSIエスケープコードの一覧表 |

## 表示項目

| 項目名 | 表示内容 | 備考 |
|--------|----------|------|
| セクションタイトル | "Utilities" | ページ見出し（h1） |
| Timers (h2) | uv_timer_tの使用法 | コードブロック複数 |
| Event loop reference count (h2) | uv_ref/uv_unref | ref-timer/main.c |
| Idler pattern (h2) | Idleハンドルの活用 | idle-compute/main.c |
| Passing data to worker thread (h2) | batonパターン | コードブロック複数 |
| External I/O with polling (h2) | uv_poll使用法 | uvwget/main.c (libcurl) |
| Check & Prepare watchers (h2) | 未完成（TODO） | 内容なし |
| Loading libraries (h2) | uv_dlopen/dlsym | plugin/ |
| TTY (h2) | uv_tty_t制御 | tty/main.c, tty-gravity/main.c |
| エスケープコード表 | 2J/H/nB/nC/m の意味 | reStructuredTextテーブル |
| versionchanged | 1.23.1でreadableパラメータが自動検出に変更 | Sphinxディレクティブ |

## イベント仕様

### 1-タイマーの動作パターン

```c
uv_timer_init(loop, &timer_req);
uv_timer_start(&timer_req, callback, 5000, 2000);  // 5秒後に初回、2秒毎にリピート
uv_timer_stop(&timer_req);  // 停止
```

### 2-参照カウントによるループ終了制御

ref-timer/main.cで示されるパターン：
1. GCタイマーを起動（2秒間隔）
2. uv_unref()で参照カウントから除外
3. 9秒のfake_jobタイマーが完了するとGCタイマーが残っていてもループ終了

### 3-外部I/Oポーリング（uvwget）

libcurlのマルチインターフェースとlibuvのuv_poll_tを組み合わせ、ダウンロード処理をイベントループで駆動する。

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | 静的HTMLページのため該当なし |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| N-39-01 | 注記 | "The shared library filename will be different depending on platforms..." | Loading librariesセクション |
| V-39-01 | バージョン変更 | "1.23.1: the readable parameter is now unused and ignored." | TTYセクション末尾 |

## 例外処理

静的HTMLページのため、アプリケーションレベルの例外処理は発生しない。

## 備考

- "Check & Prepare watchers" セクションはTODOとして未完成のままである。
- uv_timer_set_repeat()はコールバック内から呼ばれた場合、次の1回は古いintervalが使用され、その後新しいintervalに切り替わる。
- uv_timer_again()はリピートタイマーにのみ適用可能。非リピートタイマーではUV_EINVALエラーとなる。
- batonパターンの名称はKonstantin Kaeferの資料に由来する。
- uvwgetサンプルはlibcurlのCURL_SOCKET_TIMEOUTとuv_timer_tの連携、およびuv_poll_tとcurl_multi_socket_actionの連携を示す。
- TTYセクションではuv_guess_handle()でFDがTTYかどうかを判定し、リダイレクト時にエスケープコードを出力しないようにする方法が説明されている。
- 脚注として、batonの由来とmfpプラグインの説明が含まれる。

---

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

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

### 推奨読解順序

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

タイマー、Idle、poll、TTY各ハンドルの型と使用パターンを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | utilities.rst | `docs/src/guide/utilities.rst` | 行9-55: タイマーの基本（init/start/stop/set_repeat/again） |
| 1-2 | utilities.rst | `docs/src/guide/utilities.rst` | 行136-187: batonパターンの構造体定義 |

**読解のコツ**: uv_timer_startの第3引数がtimeout（初回発火まで）、第4引数がrepeat（繰り返し間隔）。repeat=0で1回限りのタイマー。

#### Step 2: 参照カウントとIdlerパターンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ref-timer/main.c | `docs/code/ref-timer/main.c` | 行17-29: main関数 -- gc_reqのuv_unrefパターン |
| 2-2 | idle-compute/main.c | `docs/code/idle-compute/main.c` | 行34-43: main関数 -- idle + stdin読み取り並行 |
| 2-3 | idle-compute/main.c | `docs/code/idle-compute/main.c` | 行10-18: crunch_away -- idle内の処理 |

**主要処理フロー（ref-timer/main.c）**:
1. **行20**: `uv_timer_init(loop, &gc_req)` -- GCタイマー初期化
2. **行21**: `uv_unref((uv_handle_t*)&gc_req)` -- 参照カウントから除外
3. **行23**: `uv_timer_start(&gc_req, gc, 0, 2000)` -- 即座に開始、2秒間隔
4. **行26-27**: fake_jobタイマー -- 9秒後に1回だけ発火
5. 9秒後、fake_job完了 → gc_reqはunrefされているためループ終了

#### Step 3: 外部I/Oポーリング（uvwget）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | uvwget/main.c | `docs/code/uvwget/main.c` | 行142以降: main関数 -- curl初期化とソケット/タイムアウトコールバック設定 |
| 3-2 | uvwget/main.c | `docs/code/uvwget/main.c` | 行102-140: handle_socket -- uv_poll_tでソケット監視 |
| 3-3 | uvwget/main.c | `docs/code/uvwget/main.c` | 行81-95: curl_perform -- curl_multi_socket_action駆動 |

#### Step 4: TTY制御を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | tty/main.c | `docs/code/tty/main.c` | 全体: uv_tty_init → uv_tty_set_mode → ANSIエスケープ出力 |
| 4-2 | tty-gravity/main.c | `docs/code/tty-gravity/main.c` | 全体: uv_tty_get_winsize → アニメーション |

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

```
ref-timer/main.c
    |
    +-- uv_timer_init(loop, &gc_req)
    +-- uv_unref(&gc_req) [参照カウント除外]
    +-- uv_timer_start(&gc_req, gc, 0, 2000)
    +-- uv_timer_init(loop, &fake_job_req)
    +-- uv_timer_start(&fake_job_req, fake_job, 9000, 0)
    +-- uv_run(loop, UV_RUN_DEFAULT)

uvwget/main.c
    |
    +-- curl_global_init()
    +-- uv_timer_init(loop, &timeout)
    +-- curl_multi_init()
    +-- curl_multi_setopt(SOCKETFUNCTION, handle_socket)
    +-- curl_multi_setopt(TIMERFUNCTION, start_timeout)
    +-- curl_easy_init() [URL毎]
    |       +-- curl_multi_add_handle()
    +-- uv_run(loop, UV_RUN_DEFAULT)
            |
            +-- start_timeout() --> uv_timer_start()
            +-- handle_socket() --> uv_poll_init_socket() / uv_poll_start()
            +-- curl_perform() --> curl_multi_socket_action()
                    +-- check_multi_info() --> curl_easy_cleanup()
```

### データフロー図

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

timeout値 (libcurl)      --> uv_timer_start()            --> タイムアウト時に駆動
ソケット状態 (libcurl)   --> uv_poll_start()             --> I/O Ready時に駆動
I/O Ready通知            --> curl_multi_socket_action()  --> ダウンロード進捗
ダウンロード完了         --> check_multi_info()          --> ファイル出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| utilities.rst | `docs/src/guide/utilities.rst` | テンプレート | ユーティリティガイドページ本体 |
| guide.rst | `docs/src/guide.rst` | テンプレート | 親ページ |
| ref-timer/main.c | `docs/code/ref-timer/main.c` | ソース | 参照カウントサンプル |
| idle-compute/main.c | `docs/code/idle-compute/main.c` | ソース | Idlerパターンサンプル |
| uvwget/main.c | `docs/code/uvwget/main.c` | ソース | libcurl連携サンプル |
| plugin/main.c | `docs/code/plugin/main.c` | ソース | プラグインシステムサンプル |
| plugin/hello.c | `docs/code/plugin/hello.c` | ソース | サンプルプラグイン |
| plugin/plugin.h | `docs/code/plugin/plugin.h` | ソース | プラグインインターフェース |
| tty/main.c | `docs/code/tty/main.c` | ソース | TTY基本サンプル |
| tty-gravity/main.c | `docs/code/tty-gravity/main.c` | ソース | TTYアニメーションサンプル |
| conf.py | `docs/src/conf.py` | 設定 | Sphinxビルド設定 |
