Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
reload_library.hpp File Reference

Dynamic-library handle for the DSP hot-reload path, with an explicit and deliberately conservative leak policy. More...

#include <string>
#include <utility>
#include <dlfcn.h>

Go to the source code of this file.

Classes

class  pulp::format::reload::ReloadLibrary

Namespaces

namespace  pulp
namespace  pulp::format
 What the product grants a device: the quota table indexed by capability tier and live thermal state.
namespace  pulp::format::reload

Enumerations

enum class  pulp::format::reload::LeakPolicy { pulp::format::reload::Retain , pulp::format::reload::CloseOnDestroy }
 What the handle does with the loaded image when it is destroyed. More...

Functions

void pulp::format::reload::promote_host_symbols_once ()
 Promote the HOST image's symbols to global loader scope, once per process

Detailed Description

Dynamic-library handle for the DSP hot-reload path, with an explicit and deliberately conservative leak policy.

THE LEAK POLICY — why the default is to NOT unload: Once a freshly-built logic library has been dlopened and a Processor constructed from it, that instance's code, vtables, RTTI, inline functions, thread-locals, and any registered atexit/static-destructor handlers all live inside the loaded image. dlcloseing the image while any of that is still reachable — even after the audio thread has been swapped off the old processor — is a use-after-free waiting to happen: a queued UI callback, a pending exception unwinding through the image, a TLS destructor, or a std::function holding a lambda defined in the image will all jump into freed pages. There is no portable way to prove an image is fully quiesced. So a live reload session deliberately STACKS loaded images and leaks their handles for the process lifetime (LeakPolicy::Retain, the default). The leak is bounded — one handle per successful reload during a dev session — and is the correct trade against an unload-race crash.

LeakPolicy::CloseOnDestroy is opt-in for callers that can guarantee the image never contributed a still-live object: a scratch probe that only read a build fingerprint / parameter contract and instantiated nothing, or a teardown path in a test. Use it only when that guarantee holds.

The wrapper is intentionally dependency-light (mirrors the self-contained shape of build_fingerprint.hpp) and carries its own minimal cross-platform loader surface rather than depending on the host layer's dl_shim.hpp, so the reload primitives stay loadable below the host.