diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2023-01-21 11:13:04 -0500 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2023-07-13 12:49:09 -0400 |
commit | c747ff0925fb85147a96745bb55e66e7e8004fd8 (patch) | |
tree | 4b9eb47db9352156e62a080f335d331b70bb82ef /indra/llcommon/llthreadsafequeue.h | |
parent | 2c894ecb25de044f5cb9c408c5264e5234b73983 (diff) |
DRTVWR-558: Enrich LLEventDispatcher::callFail() with current call.
Now an LLEventAPI subclass method can call callFail(...) to report an error,
and the error will be annotated with the leaf class name, the instance name
and the way the method was reached. The enriched error message will be logged
and either sent back to the invoker or propagated as an exception, depending
on the invocation tactic. In other words, a business method can use callFail()
to Do The Right Thing according to the LLEventDispatcher contract.
Introduce a nested SetState RAII class to set and clear transient state.
SetState's constructor accepts variadic stringize() arguments. The resulting
message is passed to LLEventDispatcher::setState(), which requires a SetState
reference because ONLY SetState should call setState(): state data really is
intended to be transient. SetState guarantees it will be cleared every time
it's set.
setState() respects previously-set transient state. If a call from an inner
function finds that transient state was already set by some ancestor, it
ignores the call and informs the caller by returning false. This lets a given
SetState instance recognize whether it is responsible for clearing the current
transient state.
operator<<(std::ostream&, const LLEventDispatcher&) now appends getState() to
the data reported by streaming *this. Non-static LLEventDispatcher::callFail()
already prepends *this to the reported error message.
Transient state is managed by a fiber_specific_ptr, since different threads
and even different fibers within a thread might be concurrently performing
different operations on the same LLEventDispatcher.
Introduce a back pointer to the parent LLEventDispatcher in DispatchEntry.
Populate it with a new constructor parameter, propagated through every
subclass constructor. Hoist ParamsDispatchEntry::callFail() up into its
DispatchEntry base class. Make it call non-static LLEventDispatcher::
callFail(), which prepends the reported error with instance and transient
state info. Use DispatchEntry::callFail() in LLSDDispatchEntry::call(),
instead of redundantly calling LLEventDispatcher::callFail().
Similarly, introduce an LLEventDispatcher back pointer into LLSDArgsMapper for
use by its own callFail() method.
The above should (!) eliminate the need to replicate LLEventDispatcher
instance info into every helper object's descriptive strings. In particular,
since the previous info was stored in each object by its constructor, it
couldn't report associated transient information about how the subject
callable was actually reached. Traversing a back pointer to the live
LLEventDispatcher instance gets us the most current state.
Make the internal three-argument LLEventDispatcher::try_call() method, which
implements each of the operator()() and public try_call() methods, use
SetState to append "[name]" (for explicit operator()(name, event) calls) or
"[key=name]" (for implicit operator()(event) calls) to streamed *this.
In the new LLDispatchListener request array and request map operations, use
SetState to indicate the current entry in the array or map, overriding the
lower-level state set by three-argument LLEventDispatcher::try_call().
(cherry picked from commit 2f8d7d20f43ab411ea0fe8b756cb696954acfb3e)
Diffstat (limited to 'indra/llcommon/llthreadsafequeue.h')
0 files changed, 0 insertions, 0 deletions