SafeSignal could queue events forever when worker threads emitted faster than
the main loop could consume, which risks memory growth and stale updates.
I added a queue cap with a drop-oldest policy so growth stays bounded under
burst load, plus a regression test that validates bounded delivery.
Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
Implement a wrapper over Glib::Dispatcher that passes the arguments to
the signal consumer via synchronized `std::queue`.
Arguments are always passed by value and the return type of the signal
is expected to be `void`.