Skip to content

Image and label permissions are now stored in each action instead of relying on an index - #130

Closed
gensyn wants to merge 4 commits into
StreamController:mainfrom
gensyn:image_and_labels
Closed

gensyn wants to merge 4 commits into
StreamController:mainfrom
gensyn:image_and_labels

Conversation

@gensyn

@gensyn gensyn commented Jun 12, 2024

Copy link
Copy Markdown
Contributor

No description provided.

@Core447

Core447 commented Jun 14, 2024

Copy link
Copy Markdown
Member

I'm waiting with the merge until the stream-deck-plus branch is finished and merged

@Core447

Core447 commented Jun 16, 2024

Copy link
Copy Markdown
Member

Tbh I prefer the way current way of storing the permissions, but I see your point: Your approach is less likely to cause problems. Can you please check if you're still experiencing this issue on the head of main (changed some stuff)?

@gensyn gensyn closed this by deleting the head repository Jul 18, 2024
nazbert added a commit to nazbert/Deckard that referenced this pull request Jul 12, 2026
…treamController#8 review round 1)

Adds two checks to scenario_touchscreen_slot_race.py, closing the review
gap on the sites most entangled with the merged !27 write-cap:

- check_writecap_putback: the !27 rate-cap re-queues an over-budget
  touchscreen frame into the single slot iff still None. The
  None-check-then-set is now under _slot_lock; the test forces a producer
  to assign a NEWER frame into the check->set window (via a hook on the
  putback's own 2nd slot read) and asserts it survives -- AND that the
  deferred over-budget frame is NOT written to the device, so the !27
  rate-limit is preserved (no write-flood). Red-checked: with only the
  putback lock reverted (all other locks intact), FAIL(3) fires -- the
  newer frame is clobbered by the older deferred frame.
- check_slot_wipes: clear_media_player_tasks (the one nested
  _page_gen_lock -> _slot_lock ordering) and _exec_clear_and_close both
  leave a coherent, wiped slot with no lock inversion.

hook_types gains a fire-on-Nth-read mode so a test can target the
putback read without firing on the drain's earlier read.

Also documents (NIT) that the has_pending slot reads in _run_one_tick are
intentionally unlocked -- a torn read only mis-picks target FPS for one
tick and self-corrects. The producer-vs-producer submit-seq inversion
(last-assigner-wins, pre-existing, out of StreamController#8's scope) is tracked in StreamController#130.
nazbert added a commit to nazbert/Deckard that referenced this pull request Jul 12, 2026
…roller#130)

add_touchscreen_task/add_image_task allocated next_submit_seq() and
built the task outside _slot_lock, locking only the slot assignment.
Two concurrent producers (media-tick strip update vs. a dial update on
a GTK/action thread; or two writers of one key slot) could allocate
seqs in one order and assign in the other -- the single slot kept the
LOWER-seq (older) frame and the newer one was lost: one-frame staleness
for animated content under concurrent updates.

Stamp+assign are now atomic under _slot_lock, so seq order is
assignment order and a slot always ends holding the highest allocated
seq; the Clear "survives if submitted after" comparison stays
consistent with what the slot actually holds.

New tests/scenario_slot_seq_wins.py stresses 8 producers x 25 frames
per slot kind with jitter injected into a recording next_submit_seq
wrapper (which sits exactly in the old allocate->assign window) and
asserts the slot ends with max(recorded seq). Red-tested: on the
pre-fix code the key-slot leg fails with an older frame overwriting a
newer one. Suite: 111 passed, 3 expected-fail, 0 failed (of 114).
nazbert added a commit to nazbert/Deckard that referenced this pull request Jul 12, 2026
The original scenario_slot_seq_wins relied on random per-allocation jitter
and only compared the FINAL slot value against max(recorded); the producer
inversion it targets surfaced there ~25% of runs, so the guard passed on the
buggy (stamp-outside-_slot_lock) code most of the time -- effectively vacuous
for CI.

Force the inversion deterministically instead: the wrapped next_submit_seq
sleeps AFTER allocation for a time that decreases with the seq's position in
the round (earliest seq sleeps longest). Pre-fix, that sleep is in the
allocate->assign window outside _slot_lock, so the lowest-seq producer assigns
last and overwrites the slot with the oldest frame -- every round (measured
200/200, and 10/10 whole-suite runs fail in round 0). With the fix the sleep
runs under _slot_lock, so assignment order follows seq order and the slot
always holds the round max (0 inversions). Runs per round instead of one big
jittered stress; ~0.65s, no watchdog-timeout dead time.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants