A FIFO (ticket) mutex.
open62541's UA_Client* is single-threaded, so the iterator thread and every public data-plane op (Read/Write/Call/...) must serialise on one lock. With a plain std::mutex that lock is UNFAIR: the hot contender (the iterator looping on run_iterate, or one busy reader thread) keeps winning the re-acquire race and the other contenders starve — measured at up to ~3.3 s of wait under a 4-thread read load with a live subscription.
This ticket lock serves contenders strictly in arrival order: a caller takes the next ticket and waits until "now serving" reaches it. Worst-case wait for any contender is therefore bounded by the number of contenders ahead of it times their critical-section length (one run_iterate slice ~5 ms, or a single SDK read ~1 ms) — no starvation regardless of thread count.
Satisfies BasicLockable (lock/unlock) so it drops into std::lock_guard. Blocking is via a condition_variable, so waiters do not spin.