The callbacks an object calls when something happens - each added, and removed by the ID Add gave it - with the guarantees that needs when they are called on a thread of the object's own, and added and removed on others. More...
The callbacks an object calls when something happens - each added, and removed by the ID Add gave it - with the guarantees that needs when they are called on a thread of the object's own, and added and removed on others.
o Call holds no lock while a callback runs. So Add never waits for a running callback, and a callback may Add, Remove (itself too) or Call, or wait for a thread doing so. o Once Remove returns, that callback is not running, and is never called again - except that, called from within that very callback, the call already under way finishes. So Remove waits for a call running on another thread: do not call it holding a lock that callback takes. o An exception from a callback is logged (DbgTrace) and ignored, and the rest are still called - except Thread::AbortException, which ends the Call, so its thread can end. o 'Before' and 'after' are as the registry's lock orders them - each Add, Remove and RemoveAll, and the start of each Call, takes it in turn (from different threads at once, in no defined order). So a Call calls the callbacks added before it started, and not removed since: one added during a Call is first called by the next.
Its lock is a plain (non-recursive) mutex, held only to read or update the list of callbacks - never while one runs, so nothing can re-enter it - and so cheap: one uncontended lock to Add or Remove; to Call, one, and two more for each callback it runs. (A use that cannot afford even that need not use this.)
Definition at line 83 of file CallbackRegistry.h.