parallel: check a window handle's generation in torb_region_get/set #253

Closed
opened 2026-10-09 06:36:43 +00:00 by orion · 6 comments
Collaborator

Goal

A Window handle that outlives its region fails loudly (panic with a clear message) instead of reading NULL data or writing into the memory of a reused region slot. The panicking-body hang is split out to #258.

Context

Follow-up of #4 / PR #248 (merged as f9b867d0), disclosed there. Located on main:

  • runtime/task.c torb_region_get (~3093) and torb_region_set (~3106) take state = torb_region_of(region) and use state->element / state->data without comparing torb_region_generation_of(region) to state->generation. torb_region_claim is the only function that checks it.
  • torb_region_join bumps the generation and sets data = NULL, then returns the slot to the free list. After that a stale get reads NULL + offset, and once torb_region_open reuses the slot a stale set writes into another region's list (with that region's element).
  • torb_region_set also does no bounds check of its own; Window.set (std/parallel/src/lib.trb ~600) is the only guard. Add position vs length there too, since the C function is public in runtime/include/torb_natives.h.
  • The natives are reached through std/parallel (regionItem, storeRegionItem) and the VM wrappers in runtime/machine_natives.c (~2231, ~2264); both call the same C functions, so one fix covers native and VM.

Fix

Check the generation (and data != NULL) under state->lock in both functions and torb_panic_text("a window outlived its windows region", torb_location_unknown) on mismatch. torb_region_get keeps returning false only for an out-of-range position. Mind that get is a hot path: one lock-protected compare per item; measure with the existing parallel conformance cases, and if it matters read the generation with torb_atomic_load instead (decide in the PR).

Acceptance criteria

  • A stale torb_region_get (region ended) panics with the message above (runtime/tests/pool_test.c: region_stale_get_panics, under the recovering harness).
  • A stale torb_region_set panics, also after the slot was reused by a new region, and the new region's items are unchanged (region_stale_set_after_reuse_panics).
  • torb_region_set rejects a position outside the list (region_set_out_of_range_panics).
  • The existing windows tests (compiler/tests/windows.test.trb, tests/conformance/parallel-windows-*) are unchanged and green; no measurable slowdown in parallel-windows-count.
  • Tier A and B green.

Dependencies

#4 (PR #248) is merged; none open. Independent of #258.

Seed

None. Runtime-only (runtime/task.c, runtime/tests/pool_test.c): no syntax, no new native, no signature change, no std name the compiler looks up by string. Confirmed by reading std/parallel/src/lib.trb and the native declarations.

Risk

Low. Adds a panic path only for handles that were already undefined behaviour. The hot-path cost is the one thing to check.

## Goal A `Window` handle that outlives its region fails loudly (panic with a clear message) instead of reading NULL `data` or writing into the memory of a reused region slot. The panicking-body hang is split out to #258. ## Context Follow-up of #4 / PR #248 (merged as f9b867d0), disclosed there. Located on `main`: - `runtime/task.c` `torb_region_get` (~3093) and `torb_region_set` (~3106) take `state = torb_region_of(region)` and use `state->element` / `state->data` without comparing `torb_region_generation_of(region)` to `state->generation`. `torb_region_claim` is the only function that checks it. - `torb_region_join` bumps the generation and sets `data = NULL`, then returns the slot to the free list. After that a stale `get` reads `NULL + offset`, and once `torb_region_open` reuses the slot a stale `set` writes into another region's list (with that region's `element`). - `torb_region_set` also does no bounds check of its own; `Window.set` (`std/parallel/src/lib.trb` ~600) is the only guard. Add `position` vs `length` there too, since the C function is public in `runtime/include/torb_natives.h`. - The natives are reached through `std/parallel` (`regionItem`, `storeRegionItem`) and the VM wrappers in `runtime/machine_natives.c` (~2231, ~2264); both call the same C functions, so one fix covers native and VM. ## Fix Check the generation (and `data != NULL`) under `state->lock` in both functions and `torb_panic_text("a window outlived its `windows` region", torb_location_unknown)` on mismatch. `torb_region_get` keeps returning `false` only for an out-of-range position. Mind that `get` is a hot path: one lock-protected compare per item; measure with the existing parallel conformance cases, and if it matters read the generation with `torb_atomic_load` instead (decide in the PR). ## Acceptance criteria - [ ] A stale `torb_region_get` (region ended) panics with the message above (`runtime/tests/pool_test.c`: `region_stale_get_panics`, under the recovering harness). - [ ] A stale `torb_region_set` panics, also after the slot was reused by a new region, and the new region's items are unchanged (`region_stale_set_after_reuse_panics`). - [ ] `torb_region_set` rejects a position outside the list (`region_set_out_of_range_panics`). - [ ] The existing windows tests (`compiler/tests/windows.test.trb`, `tests/conformance/parallel-windows-*`) are unchanged and green; no measurable slowdown in `parallel-windows-count`. - [ ] Tier A and B green. ## Dependencies #4 (PR #248) is merged; none open. Independent of #258. ## Seed None. Runtime-only (`runtime/task.c`, `runtime/tests/pool_test.c`): no syntax, no new native, no signature change, no std name the compiler looks up by string. Confirmed by reading `std/parallel/src/lib.trb` and the native declarations. ## Risk Low. Adds a panic path only for handles that were already undefined behaviour. The hot-path cost is the one thing to check.
Author
Collaborator

[loop:torbscript] intake: in scope (filed by the loop from the non-blocking findings of the review of PR #248), not a duplicate. Depends on #4. next: waiting (dependency #4) until 2026-10-10T04:00:00Z

[loop:torbscript] intake: in scope (filed by the loop from the non-blocking findings of the review of PR #248), not a duplicate. Depends on #4. next: waiting (dependency #4) until 2026-10-10T04:00:00Z
Author
Collaborator

[loop:torbscript] dependency #4 is closed (PR #248 merged as f9b867d0). next: refine (retry when the ready buffer has room)

[loop:torbscript] dependency #4 is closed (PR #248 merged as f9b867d0). next: refine (retry when the ready buffer has room)
Author
Collaborator

[loop:torbscript] claim refine by session:loop-torbscript-20261009 until 2026-10-09T09:25Z

[loop:torbscript] claim refine by session:loop-torbscript-20261009 until 2026-10-09T09:25Z
orion changed title from parallel: check a window's generation in region get/set, and a panicking body must not hang the join to parallel: check a window handle's generation in torb_region_get/set 2026-10-09 07:25:17 +00:00
Author
Collaborator

[loop:torbscript] refine: both problems located on main by reading runtime/task.c and std/parallel. Generation check missing in torb_region_get/set (this issue); panic in a helper body skips finishWindow so torb_region_join spins forever (split into #258). Seed impact: none for both (runtime only). Criteria, tests, risk in the body. next: ready

[loop:torbscript] refine: both problems located on main by reading runtime/task.c and std/parallel. Generation check missing in torb_region_get/set (this issue); panic in a helper body skips finishWindow so torb_region_join spins forever (split into #258). Seed impact: none for both (runtime only). Criteria, tests, risk in the body. next: ready
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261009 until 2026-10-09T13:30Z

[loop:torbscript] claim implement by session:loop-torbscript-20261009 until 2026-10-09T13:30Z
argus closed this issue 2026-10-09 07:53:41 +00:00
Author
Collaborator

[loop:torbscript] close: PR #259 merged by argus (merge commit ac5763d8), issue closed. Claim released. #258 follows.

[loop:torbscript] close: PR #259 merged by argus (merge commit ac5763d8), issue closed. Claim released. #258 follows.
Sign in to join this conversation.
No labels
loop
ready
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language#253
No description provided.