# wasmer-0002: WasiThread signal Vec<Signal> O(n) dedup on every signal delivery

**Severity:** MEDIUM
**CWE:** CWE-407 (Algorithmic Complexity — linear membership test in hot path)
**Speedup:** ~30x at S=30 signals (bounded by POSIX signal count)
**Target:** wasmer (wasmerio/wasmer)
**Files:**
- `lib/wasix/src/os/task/thread.rs:241` — `signals: Mutex<(Vec<Signal>, Vec<Waker>)>`
- `lib/wasix/src/os/task/thread.rs:351` — `if !guard.0.contains(&signal)`
- `lib/wasix/src/os/task/thread.rs:358-365` — `has_signal()` — nested O(n*m) scan

## Description

`WasiThread.signal()` adds a signal to a `Vec<Signal>` after first checking
whether it is already present using `Vec::contains()` — an O(n) scan.

`has_signal(signals: &[Signal])` performs a nested O(n * m) scan: for each
pending signal in `guard.0`, it checks whether `signals` (the query slice)
contains it using another linear scan.

While the number of distinct POSIX signals is bounded (~30), signals can be
delivered rapidly by the host OS or by other Wasm threads. In a
multi-threaded WASI application, `signal()` is called on every signal delivery
and `has_signal()` is called in polling loops. The O(n) cost here is avoidable
with a `[bool; 32]` or `u64` bitmask.

## Root Cause

Using `Vec<Signal>` for a set whose domain is bounded to ~30 values. A fixed-
size bitmask provides O(1) insert, O(1) contains, and O(1) intersection.

## Patch

See `patch/wasmer-0002.patch`

## Complexity Before

`signal()`: O(S) per call where S = number of pending signals (≤ 30)
`has_signal(q)`: O(S * Q) per call where Q = len of query slice

## Complexity After

`signal()`: O(1) — bit set
`has_signal(q)`: O(Q) — one bitmask AND operation

## Reproduction

```
cd defects/wasmer/unit && javac -d . *.java && java -ea unit.SignalVecDedupTest
```
