cross-process, crash-safe named reference count
Holding an instance signals "I am interested in the named resource" to every other process doing the same under the same name - no explicit acquire/release protocol beyond construction/release() is needed. Each holder keeps a shared (LOCK_SH) advisory lock open on a small marker file; the kernel unconditionally releases a process' flock()s when its last file descriptor to the file closes, termination/crash included - so unlike a value manually incremented/decremented in shared memory, this can never desync when a holder disappears without an orderly release() (dx::shared::memory inherits from this class for exactly that reason: release()'s own return value - "was this the last holder" - drives shm_unlink() on the last free(), replacing what used to be a separate, crash-unsafe mapped counter. Whether the shared memory is currently in use is answered separately, by a cheap shm_open-without-O_CREAT existence probe - joined is not involved in that anymore). The marker file itself is intentionally never unlinked - same as the named semaphores in shared::event - so a later reference under the same name simply reopens it; that costs nothing since flock()s are per-open-file-description, not per-path.
release() reports whether this was the last remaining holder, so the caller can decide whether it is now safe to erase whatever this name was guarding (e.g. a per-process preference store).
joined reports the opposite end of the same lifetime: whether this instance's own initialize() found another holder already present, or was the first. Constructing a throwaway instance and discarding it again (destructor/free()) right after reading joined therefore doubles as a non-destructive, repeatable "is anyone (else) currently interested in this name" probe, without disturbing any lasting holder.
Holding an instance signals "I am interested in the named resource" to every other process doing the same under the same name - no explicit acquire/release protocol beyond construction/release() is needed. The underlying named mutex is kept alive by Windows for as long as any process holds an open handle to it, and Windows unconditionally closes all of a process' handles on termination, crash included - so unlike a value manually incremented/decremented in shared memory, this can never desync when a holder disappears without an orderly release() (e.g. dx::service::client::_device's own per-application reference, whose release() return value gates whether that application's non-persistent device settings get erased on disconnect). dx::shared::memory (Windows) does NOT use this class at all - the underlying file mapping kernel object is itself already Windows' own crash-safe "is anyone still using this" primitive, kept alive exactly as long as any process holds a real, mapped handle to it, so a cheap existence probe (open the mapping by name, then immediately close) answers that question directly, with no separate reference count needed.
release() reports whether this was the last remaining holder, so the caller can decide whether it is now safe to erase whatever this name was guarding (e.g. a per-process registry-backed preference store).
joined reports the opposite end of the same lifetime: whether this instance's own initialize() found another holder already present, or was the first. Constructing a throwaway instance and discarding it again (destructor/free()) right after reading joined therefore doubles as a non-destructive, repeatable "is anyone (else) currently interested in this name" probe, without disturbing any lasting holder.