# 機能設計書 37-ブロッキングモード設定

## 概要

本ドキュメントは、libuvにおけるブロッキングモード設定機能（uv_stream_set_blocking()）の設計仕様を記述する。ストリームをブロッキング/ノンブロッキングモードに切り替える機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：libuvのストリームはデフォルトでノンブロッキングモードで動作する。しかし、特定のユースケース（子プロセスのstdioパイプなど）ではブロッキングモードが必要になる場合がある。uv_stream_set_blocking()はストリームのI/Oモードを切り替え、書き込み時の動作を制御する。

**機能の利用シーン**：子プロセスのstdioパイプにブロッキング書き込みを行う場合、同期的なI/O操作が必要な特殊なケースに使用される。

**主要な処理内容**：
1. Unix: uv__nonblock()マクロを使ってfcntl()でO_NONBLOCKフラグを設定/クリア
2. Windows: UV_HANDLE_BLOCKING_WRITESフラグの設定/クリア（名前付きパイプのみ対応）

**関連システム・外部連携**：Unix: fcntl()システムコール、Windows: 内部フラグ管理。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | ストリーム | 主機能 | uv_stream_set_blocking()によるブロッキング/ノンブロッキング設定のAPI定義 |

## 機能種別

設定変更処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | uv_stream_t* | Yes | 対象ストリーム | NULLでないこと |
| blocking | int | Yes | ブロッキングモードのオン/オフ | 非ゼロ: ブロッキング、0: ノンブロッキング |

### 入力データソース

アプリケーションコードからの直接呼び出し。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 0: 成功、負値: エラーコード |

### 出力先

ストリームのI/Oモード（ファイルディスクリプタのフラグ）が変更される。

## 処理フロー

### 処理シーケンス

```
[Unix]
1. uv__nonblock(uv__stream_fd(handle), !blocking)を呼び出し
   └─ fcntl()でO_NONBLOCKフラグを設定/クリア

[Windows]
1. ハンドル型チェック（UV_NAMED_PIPEでなければUV_EINVAL）
2. blockingフラグに応じてUV_HANDLE_BLOCKING_WRITESフラグを設定/クリア
```

### フローチャート

```mermaid
flowchart TD
    A[uv_stream_set_blocking 呼び出し] --> B{プラットフォーム}
    B -->|Unix| C[uv__nonblock で fcntl 呼び出し]
    C --> D{成功?}
    D -->|Yes| E[0 返却]
    D -->|No| F[エラーコード返却]
    B -->|Windows| G{UV_NAMED_PIPE?}
    G -->|No| H[UV_EINVAL 返却]
    G -->|Yes| I{blocking?}
    I -->|Yes| J[BLOCKING_WRITES フラグ設定]
    I -->|No| K[BLOCKING_WRITES フラグクリア]
    J --> L[0 返却]
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-37-01 | Windows制限 | Windowsでは名前付きパイプのみブロッキングモードをサポート | Windows環境 |
| BR-37-02 | Unix全対応 | Unix環境ではすべてのストリーム型でブロッキングモード切替が可能 | Unix環境 |
| BR-37-03 | 書き込み動作への影響 | ブロッキングモードではuv__write()がEAGAIN時にループ内でリトライする | ブロッキングモード時 |

### 計算ロジック

特になし。

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

該当なし。

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

該当なし。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | 入力エラー | Windows: 名前付きパイプ以外のストリーム | 対応ストリーム型を使用 |
| UV_EBADF | 状態エラー | Unix: FDが無効 | ストリームの状態を確認 |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- Unix: fcntl()システムコール1回のオーバーヘッド
- Windows: フラグ操作のみでシステムコールなし

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

- ブロッキングモードの使用はイベントループをブロックする可能性があるため、注意が必要

## 備考

- Unix実装ではFDのバリデーションを関数内で行わず、uv__nonblock()の戻り値でEBADFを検出する
- ブロッキングモード時、uv__write()内で書き込みがEAGAINの場合にcontinueでループする（stream.c L880-881参照）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | **582行目**: uv_stream_set_blocking()のAPI宣言 |

**読解のコツ**: blocking引数が非ゼロでブロッキング、0でノンブロッキング。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | stream.c | `src/unix/stream.c` | **1570-1575行目**: Unix版の実装 |

**主要処理フロー**:
- **1574行目**: `return uv__nonblock(uv__stream_fd(handle), !blocking);`

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | stream.c | `src/win/stream.c` | **268-278行目**: Windows版の実装 |

**主要処理フロー**:
- **269-270行目**: UV_NAMED_PIPEでなければUV_EINVAL
- **272-275行目**: フラグの設定/クリア

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

```
uv_stream_set_blocking(handle, blocking)
    │
    ├─[Unix] uv__nonblock(uv__stream_fd(handle), !blocking)
    │          └─ fcntl(fd, F_SETFL, flags)
    │
    └─[Windows] handle->flags |= UV_HANDLE_BLOCKING_WRITES
                or handle->flags &= ~UV_HANDLE_BLOCKING_WRITES
```

### データフロー図

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

handle, blocking ───▶ uv_stream_set_blocking()   ───▶ 0 or エラー
                       │
                       ├─[Unix] fcntl(O_NONBLOCK)
                       └─[Win]  フラグ操作
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | API宣言 |
| stream.c | `src/unix/stream.c` | ソース | Unix版実装 |
| stream.c | `src/win/stream.c` | ソース | Windows版実装 |
| internal.h | `src/unix/internal.h` | ヘッダ | uv__nonblockマクロ定義 |
