# 機能設計書 61-recvmmsg使用判定

## 概要

本ドキュメントは、libuvにおけるUDPハンドルのrecvmmsg使用状態を判定する機能（`uv_udp_using_recvmmsg()`）について、その設計仕様・処理フロー・プラットフォーム依存の挙動を記述する。

### 本機能の処理概要

UDPハンドルが `recvmmsg(2)` システムコールを使用してデータグラムを一括受信する設定になっているかどうかを判定する。recvmmsgは複数のメッセージを一度のシステムコールで受信できるLinux/FreeBSD/macOS固有の高性能受信メカニズムであり、本関数はその有効化状態を返す。

**業務上の目的・背景**：UDPで大量のデータグラムを受信するアプリケーション（リアルタイム通信、ゲームサーバー、DNSサーバー等）では、recvmmsgによるバッチ受信がパフォーマンスに大きく影響する。開発者がUDPハンドルの受信戦略を動的に判定し、適切なバッファ管理やコールバック処理を行うために、現在の受信モードを確認する手段が必要である。

**機能の利用シーン**：UDP受信コールバック内でバッファ管理戦略を切り替える場合や、デバッグ・ロギングで現在の受信モードを確認する場合に使用される。recvmmsg有効時は`UV_UDP_MMSG_CHUNK`フラグと`UV_UDP_MMSG_FREE`フラグによる特殊なコールバックパターンが発生するため、その挙動の事前確認にも利用される。

**主要な処理内容**：
1. UDPハンドルの内部フラグ（`UV_HANDLE_UDP_RECVMMSG`）を確認する
2. プラットフォームがrecvmmsgをサポートしているか条件コンパイルで判定する
3. 両方の条件を満たす場合に1（真）、それ以外は0（偽）を返す

**関連システム・外部連携**：Linux、FreeBSD、macOS（recvmsg_x使用）のカーネルrecvmmsg/recvmsg_xシステムコールとの連携。Windowsではrecvmmsgが利用できないため常に0を返す。

**権限による制御**：特になし。ハンドルの状態読み取りのみで権限による制御は不要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 21 | UDP | 主機能 | uv_udp_using_recvmmsg()によるrecvmmsg使用状態判定のAPI定義 |

## 機能種別

状態照会（ハンドルフラグの読み取り）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | const uv_udp_t* | Yes | recvmmsg使用状態を確認するUDPハンドル | NULLチェックなし（呼び出し側の責任） |

### 入力データソース

呼び出し元のアプリケーションコードから、初期化済みのUDPハンドルを引数として受け取る。ハンドルは`uv_udp_init_ex()`でUV_UDP_RECVMMSGフラグを指定して初期化されている場合にrecvmmsgが有効になる。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | recvmmsgが使用されている場合は1、そうでない場合は0 |

### 出力先

関数の戻り値として呼び出し元に返す。

## 処理フロー

### 処理シーケンス

```
1. プラットフォーム判定（コンパイル時）
   └─ __linux__, __FreeBSD__, __APPLE__ のいずれかが定義されているか
2. ハンドルフラグチェック
   └─ handle->flags & UV_HANDLE_UDP_RECVMMSG が真かどうか
3. 結果返却
   └─ 条件を満たす場合は1、それ以外は0を返す
```

### フローチャート

```mermaid
flowchart TD
    A[uv_udp_using_recvmmsg 呼び出し] --> B{プラットフォームは<br/>Linux/FreeBSD/macOS?}
    B -->|Yes| C{handle->flags &<br/>UV_HANDLE_UDP_RECVMMSG?}
    B -->|No| D[return 0]
    C -->|Yes| E[return 1]
    C -->|No| D
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-61-01 | プラットフォーム限定 | recvmmsgはLinux、FreeBSD、macOSでのみサポートされる | コンパイル時に判定 |
| BR-61-02 | フラグベース判定 | UV_HANDLE_UDP_RECVMMSGフラグはuv_udp_init_ex()でUV_UDP_RECVMMSGを指定した場合にのみ設定される | ハンドル初期化時 |
| BR-61-03 | Windows非サポート | Windows環境では常に0を返す | Windows環境 |

### 計算ロジック

単純なビットマスクチェック: `handle->flags & UV_HANDLE_UDP_RECVMMSG`

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

該当なし（メモリ上のフラグ参照のみ）

## エラー処理

### エラーケース一覧

本関数は読み取り専用であり、エラーを返さない。不正なハンドルポインタが渡された場合の動作は未定義である。

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

単純なフラグチェックのみのため、O(1)で完了する。パフォーマンスへの影響は無視できる。

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

該当なし。ハンドルの状態読み取りのみで、外部リソースへのアクセスは発生しない。

## 備考

- recvmmsgが有効な場合、`uv_udp_recv_cb`コールバックは通常と異なるパターンで呼び出される。各チャンクに対して`UV_UDP_MMSG_CHUNK`フラグ付きで呼ばれ、最後に`UV_UDP_MMSG_FREE`フラグ付きで呼ばれる
- macOSでは`recvmsg_x()`という独自のAPIを使用するが、本関数の判定対象に含まれる
- UV_UDP_RECVMMSGフラグは`uv_udp_init_ex()`の`flags`パラメータの上位ビット（値: 256）で指定する

---

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

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

### 推奨読解順序

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

UDPハンドルのフラグとrecvmmsg関連の定数を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv-common.h | `src/uv-common.h` | UV_HANDLE_UDP_RECVMMSGフラグ定義（120行目） |
| 1-2 | uv.h | `include/uv.h` | UV_UDP_RECVMMSG列挙値の定義（udp_flags内）、uv_udp_using_recvmmsg()のAPI宣言（795行目） |

**読解のコツ**: `uv-common.h`のフラグ定義はハンドル種別ごとに同じビット位置を再利用している。UV_HANDLE_UDP_RECVMMSGは0x04000000でUDPハンドル専用。

#### Step 2: フラグ設定の起点を理解する

recvmmsgフラグがどのように設定されるかを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv-common.c | `src/uv-common.c` | uv_udp_init_ex()での`UV_HANDLE_UDP_RECVMMSG`フラグ設定（362-364行目） |

**主要処理フロー**:
1. **350-353行目**: flagsの下位8ビットからドメイン（AF_INET等）を取得
2. **356-358行目**: 上位ビットからextra_flags（UV_UDP_RECVMMSG）を取得し、不正フラグをチェック
3. **362-364行目**: `uv__udp_init_ex()`成功後、extra_flagsにUV_UDP_RECVMMSGが含まれていれば`UV_HANDLE_UDP_RECVMMSG`フラグをハンドルに設定

#### Step 3: recvmmsg使用判定の実装を理解する

各プラットフォームでの判定ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | udp.c (Unix) | `src/unix/udp.c` | uv_udp_using_recvmmsg()のUnix実装（964-970行目） |
| 3-2 | udp.c (Win) | `src/win/udp.c` | uv_udp_using_recvmmsg()のWindows実装（187-189行目） |

**主要処理フロー**:
- **964-970行目（Unix）**: `#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)`で条件コンパイルし、フラグチェックを実行。サポート外プラットフォームでは0を返す
- **187-189行目（Windows）**: 常に0を返す

#### Step 4: recvmmsgの実際の利用箇所を理解する

判定結果がどのように使われるかを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | udp.c (Unix) | `src/unix/udp.c` | uv__udp_recvmsg()での判定使用箇所（309行目）とuv__udp_recvmmsg()のrecvmmsg呼び出し（210-278行目） |

**主要処理フロー**:
- **309行目**: `if (uv_udp_using_recvmmsg(handle))` で受信パスを分岐
- **210-278行目**: recvmmsg使用時のバッチ受信処理（バッファ分割、recvmmsg/recvmsg_x呼び出し、チャンクごとのコールバック）

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

```
uv_udp_using_recvmmsg()               [API関数]
    │
    ├─ (Unix) handle->flags チェック    [フラグ判定]
    │      └─ UV_HANDLE_UDP_RECVMMSG
    │
    └─ (Windows) return 0              [固定値返却]

呼び出し元:
uv__udp_recvmsg()                      [内部受信処理]
    │
    ├─ uv_udp_using_recvmmsg()         [判定]
    │      └─ true の場合
    │             └─ uv__udp_recvmmsg() [バッチ受信]
    │                    ├─ recvmmsg()  [Linux/FreeBSD]
    │                    └─ recvmsg_x() [macOS]
    └─ false の場合
           └─ recvmsg()                [通常受信]
```

### データフロー図

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

uv_udp_t* handle ───> uv_udp_using_recvmmsg() ───> int (0 or 1)
                        │
                        ├─ handle->flags &
                        │  UV_HANDLE_UDP_RECVMMSG
                        │
                        └─ #if defined(__linux__)
                           || defined(__FreeBSD__)
                           || defined(__APPLE__)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言（795行目）、UV_UDP_RECVMMSG列挙値定義 |
| uv-common.h | `src/uv-common.h` | ヘッダー | UV_HANDLE_UDP_RECVMMSGフラグ定義（120行目） |
| uv-common.c | `src/uv-common.c` | ソース | uv_udp_init_ex()でのフラグ設定（362-364行目） |
| udp.c (Unix) | `src/unix/udp.c` | ソース | Unix実装（964-970行目）、使用箇所（309行目） |
| udp.c (Win) | `src/win/udp.c` | ソース | Windows実装（187-189行目） |
| test-udp-mmsg.c | `test/test-udp-mmsg.c` | テスト | recvmmsg関連のテスト |
