#signals
3 posts tagged #signals.
Signals, slots and thread affinity without Qt or moc
The core of reflect-moc is signals, slots, queued and blocking connections, thread affinity and a per-thread event loop in plain C++26 with no Qt. A worker thread reports progress to an object on the main thread, and the program runs on Compiler Explorer. Under ThreadSanitizer the 18 core tests passed in the recorded run, and one test reports in 27 of 11000 repeats, a report that a 12-line std::latch program without the library also gets and that a mutex and condition variable removes.
C++26 cannot write a signal's body, so a signal became a data member
A Qt signal is a function whose body moc generates, and C++26 reflection cannot generate a function body. A callable data member does not connect, a source_location tag gives every signal the same type, and a closure tag has internal linkage. What held is a bodyless data member that finds its owner through a hidden first member: 8 bytes per signal and 8 per class, measured. A static signal costs 0 bytes and has one silent pitfall. A signal that writes its own one-line body costs nothing and is the one form for overloaded signals.
Thread-safe is not reentrant, and the difference bites
The Qt handler contract asked for a reentrant function, not just a thread-safe one, and a std::mutex gives you the second without the first. A demo shows a thread-safe counter and a reentrant recursion that needs a recursive_mutex. The precise taxonomy: reentrant implies thread-safe, never the reverse. Episode 8 of the concurrent I/O series.