45#include <system_error>
85 explicit operator bool()
const {
return ok(); }
127inline std::optional<ReloadOutcome>
139 (sig ?
"swap-pack signature rejected: " :
"swap-pack integrity rejected: ") +
153 if (trust.
srl !=
nullptr) {
157 "swap-pack signer key is revoked"};
162 "swap-pack artifact is revoked"};
175 if (std::filesystem::equivalent(trust.
pack_root / f.path, library_path, ec) && !ec) {
182 "load target is not a verified member of the swap pack"};
199inline std::variant<GatedImage, ReloadOutcome>
203 std::string
detail, std::vector<std::string> issues = {}) {
214 if (trust !=
nullptr) {
216 return std::move(*rejected);
228 "missing reload-ABI-version symbol");
231 "reload ABI version " + std::to_string(v) +
239 "missing fingerprint symbol");
241 fingerprint_fn(&logic_fingerprint);
244 "build fingerprint mismatch",
251 "missing create symbol");
275 const std::string& library_path,
279 std::vector<ReloadLibrary>& retained_images,
284 using clock = std::chrono::steady_clock;
285 const auto t0 = clock::now();
286 const auto ms = [](clock::time_point a, clock::time_point b) {
287 return std::chrono::duration<double, std::milli>(b - a).count();
294 const auto t_gate = clock::now();
295 if (
auto* rejected = std::get_if<ReloadOutcome>(&gated)) {
296 rejected->metrics.load_gate_ms = ms(t0, t_gate);
297 rejected->metrics.total_ms = ms(t0, t_gate);
298 return std::move(*rejected);
300 GatedImage& image = std::get<GatedImage>(gated);
306 retained_images.push_back(std::move(image.lib));
310 o.metrics.load_gate_ms = ms(t0, t_gate);
311 o.metrics.total_ms = ms(t0, clock::now());
320 std::unique_ptr<Processor> candidate(create_fn());
330 candidate->define_parameters(scratch);
335 const auto t_construct = clock::now();
344 candidate->set_state_store(&live_store);
345 candidate->prepare(prepare_ctx);
346 const auto t_prepare = clock::now();
359 const int probe_frames =
362 const std::size_t frames =
static_cast<std::size_t
>(probe_frames);
363 std::vector<float> in_l(frames, 0.0f), in_r(frames, 0.0f);
364 std::vector<float> out_l(frames, 0.0f), out_r(frames, 0.0f);
365 const float* in_ptrs[2] = {in_l.data(), in_r.data()};
366 float* out_ptrs[2] = {out_l.data(), out_r.data()};
370 candidate->process(probe_out, probe_in, probe_mi, probe_mo,
ProcessContext{});
371 for (std::size_t c = 0; c < probe_out.
num_channels(); ++c) {
373 for (std::size_t n = 0; n < frames; ++n) {
374 if (!std::isfinite(o[n])) {
376 "candidate produced non-finite output on a silence probe"});
382 std::unique_ptr<Processor> displaced = slot.
swap(std::move(candidate));
384 const auto t_swap = clock::now();
388 ok.metrics.construct_ms = ms(t_gate, t_construct);
389 ok.metrics.prepare_ms = ms(t_construct, t_prepare);
390 ok.metrics.swap_ms = ms(t_prepare, t_swap);
391 ok.metrics.total_ms = ms(t0, t_swap);
393 }
catch (
const std::exception& e) {
395 std::string(
"candidate threw: ") + e.what()});
398 "candidate threw (non-std exception)"});
411 : slot_(slot), live_store_(live_store),
412 host_fingerprint_(host_fingerprint), prepare_ctx_(prepare_ctx) {}
417 live_store_, prepare_ctx_, retained_images_);
428 std::vector<ReloadLibrary> retained_images_;
Strict build-compatibility fingerprint — the PRIMARY safety gate for DSP hot reload.
Non-owning view over multi-channel audio sample data.
Definition buffer.hpp:30
std::size_t num_channels() const
Definition buffer.hpp:83
std::span< SampleType > channel(std::size_t index)
Get a span over all samples in one channel.
Definition buffer.hpp:58
Collection of timestamped MIDI events within a single audio buffer period.
Definition buffer.hpp:31
Centralized parameter storage with lock-free value access.
Definition store.hpp:164
Parameter-contract equivalence check for DSP hot reload.
RT-safe hot-swap slot for a Processor.
The C-ABI contract a hot-reloadable "logic" library exports, and the macro a plugin uses to export it...
Dynamic-library handle for the DSP hot-reload path, with an explicit and deliberately conservative le...
Signed Revocation List (SRL) + namespaced monotonic epoch floor.
Definition prepare_resources.hpp:102
int max_buffer_size
Definition prepare_resources.hpp:104
Process context — passed every audio callback with transport state.
Definition process_context.hpp:89
Sealed swap-pack manifest + per-file integrity.