Skip to content

ossia: do not queue control outputs nobody reads - #208

Merged
jcelerier merged 1 commit into
mainfrom
workshop/nodal-ui-batch
Sep 21, 2026
Merged

jcelerier merged 1 commit into
mainfrom
workshop/nodal-ui-batch

Conversation

@jcelerier

@jcelerier jcelerier commented Sep 21, 2026

Copy link
Copy Markdown
Member

finish_run enqueues the control outputs onto outs_queue on every tick where any of them was written. The host does not always install a reader — ossia score only does so when its execution update setting is on — and an unread moodycamel queue grows without bound, allocating a block inside the audio callback every few hundred ticks.

A node that writes a control output every tick, which is the natural shape for a playhead or a meter, therefore leaks for the length of the run.

controls_output_queue<T> gains:

std::atomic_bool notify_ui{true};

checked before the enqueue. The outputs_set bitset is still set and reset as before — it costs nothing and other code reads it; it is the enqueue that allocates.

Defaults to true, so every binding that does not set it (Max, PD, VST, standalone) behaves exactly as today. Only a host that explicitly opts out is affected.

Read on the audio thread, written by the host at setup; relaxed ordering is sufficient, since a stale read costs at most one extra or one skipped enqueue and nothing else depends on the ordering.

Needed by ossia/score#2295, which sets it from the setting that decides whether the reader is installed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01H4N6KsxzvT1o9qoPvBThyz

finish_run enqueues the control outputs onto outs_queue on every tick where
any of them was written. The host does not always install a reader -- score
only does so when its "execution update" setting is on -- and an unread
moodycamel queue grows without bound, allocating a block inside the audio
callback every few hundred ticks.

A node that writes a control output every tick, which is the natural shape for
a playhead or a meter, therefore leaks for the length of the run. Let the host
say whether anything is listening; default true, so a binding that does not
set it behaves as before.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H4N6KsxzvT1o9qoPvBThyz
@jcelerier
jcelerier merged commit fac8a0f into main Sep 21, 2026
4 of 23 checks passed
jcelerier added a commit to ossia/score that referenced this pull request Sep 21, 2026
celtera/avendish#208 merged with a rebase, so the commit the pointer named
only ever existed on its PR branch. Point at what landed on main instead,
before that branch goes away and the submodule stops resolving.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H4N6KsxzvT1o9qoPvBThyz
jcelerier added a commit to ossia/score that referenced this pull request Sep 21, 2026
celtera/avendish#208 merged with a rebase, so the commit the pointer named
only ever existed on its PR branch. Point at what landed on main instead,
before that branch goes away and the submodule stops resolving.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H4N6KsxzvT1o9qoPvBThyz
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.

1 participant