<feed xmlns='http://www.w3.org/2005/Atom'>
<title>viewer.git/indra/llcommon/lleventdispatcher.cpp, branch cef_147</title>
<subtitle>Megapahit's fork of the Second Life viewer.
</subtitle>
<id>https://megapahit.org/viewer.git/atom?h=cef_147</id>
<link rel='self' href='https://megapahit.org/viewer.git/atom?h=cef_147'/>
<link rel='alternate' type='text/html' href='https://megapahit.org/viewer.git/'/>
<updated>2024-04-29T04:56:09Z</updated>
<entry>
<title>#824 Process source files in bulk: replace tabs with spaces, convert CRLF to LF, and trim trailing whitespaces as needed</title>
<updated>2024-04-29T04:56:09Z</updated>
<author>
<name>Andrey Lihatskiy</name>
<email>alihatskiy@productengine.com</email>
</author>
<published>2024-04-29T04:43:28Z</published>
<link rel='alternate' type='text/html' href='https://megapahit.org/viewer.git/commit/?id=1b68f71348ecf3983b76b40d7940da8377f049b7'/>
<id>urn:sha1:1b68f71348ecf3983b76b40d7940da8377f049b7</id>
<content type='text'>
</content>
</entry>
<entry>
<title>DRTVWR-587: Use [[noreturn]] attribute on callFail() methods</title>
<updated>2023-07-28T08:05:46Z</updated>
<author>
<name>Nat Goodspeed</name>
<email>nat@lindenlab.com</email>
</author>
<published>2023-07-25T15:18:12Z</published>
<link rel='alternate' type='text/html' href='https://megapahit.org/viewer.git/commit/?id=bfc9772d61cadc88b3fdf6f553c60e73c79e83ed'/>
<id>urn:sha1:bfc9772d61cadc88b3fdf6f553c60e73c79e83ed</id>
<content type='text'>
that unconditionally return. This eliminates the problem of pacifying a
compiler that expects a return statement vs. a compiler that detects that
callFail() unconditionally throws.

Thanks, Ansariel.
</content>
</entry>
<entry>
<title>DRTVWR-558: Avoid extra copy of getMetadata() LLSD map.</title>
<updated>2023-07-13T16:49:39Z</updated>
<author>
<name>Nat Goodspeed</name>
<email>nat@lindenlab.com</email>
</author>
<published>2023-03-07T22:39:03Z</published>
<link rel='alternate' type='text/html' href='https://megapahit.org/viewer.git/commit/?id=3fce3d14d6b8e367f4136efbfe87fcfcb23a4c8e'/>
<id>urn:sha1:3fce3d14d6b8e367f4136efbfe87fcfcb23a4c8e</id>
<content type='text'>
(cherry picked from commit 2c1253c8ed2a1648317e6edd768b3fda00c56ce2)
</content>
</entry>
<entry>
<title>DRTVWR-558: Fix merge glitch: missing LLEventDispatcher::addFail()</title>
<updated>2023-07-13T16:49:39Z</updated>
<author>
<name>Nat Goodspeed</name>
<email>nat@lindenlab.com</email>
</author>
<published>2023-01-24T18:31:50Z</published>
<link rel='alternate' type='text/html' href='https://megapahit.org/viewer.git/commit/?id=7c79d7a7d4d5cb1e39293cdc98fd972be5bd3012'/>
<id>urn:sha1:7c79d7a7d4d5cb1e39293cdc98fd972be5bd3012</id>
<content type='text'>
(cherry picked from commit 3be250da90dd3d361df713056b881e017684e2b3)
</content>
</entry>
<entry>
<title>DRTVWR-558: Nail down LLDispatchListener exception handling</title>
<updated>2023-07-13T16:49:09Z</updated>
<author>
<name>Nat Goodspeed</name>
<email>nat@lindenlab.com</email>
</author>
<published>2023-01-23T15:51:33Z</published>
<link rel='alternate' type='text/html' href='https://megapahit.org/viewer.git/commit/?id=2eb0ea9593d0e299445d2e1dde711bfe5072542e'/>
<id>urn:sha1:2eb0ea9593d0e299445d2e1dde711bfe5072542e</id>
<content type='text'>
for exceptions other than those thrown by base-class LLEventDispatcher.

Explain in LLDispatchListener Doxygen comments that for a request lacking a
"reply" key, any exception is allowed to propagate because it's likely to
reach the post() call that triggered the exception in the first place.

For batch LLDispatchListener operations, catch not only LLEventDispatcher::
DispatchError exceptions but any std::exception, so we can collect them to
report to the invoker. "Gotta catch 'em all!"

Make LLLeap catch any std::exception thrown by processing a request from the
plugin child process, log it and send a reply to the plugin. No plugin should
be allowed to crash the viewer.

(cherry picked from commit 94e10fd039b79f71ed8d7e10807b6e4eebd1928c)
</content>
</entry>
<entry>
<title>DRTVWR-558: Enrich LLEventDispatcher::callFail() with current call.</title>
<updated>2023-07-13T16:49:09Z</updated>
<author>
<name>Nat Goodspeed</name>
<email>nat@lindenlab.com</email>
</author>
<published>2023-01-21T16:13:04Z</published>
<link rel='alternate' type='text/html' href='https://megapahit.org/viewer.git/commit/?id=c747ff0925fb85147a96745bb55e66e7e8004fd8'/>
<id>urn:sha1:c747ff0925fb85147a96745bb55e66e7e8004fd8</id>
<content type='text'>
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&lt;&lt;(std::ostream&amp;, const LLEventDispatcher&amp;) 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)
</content>
</entry>
<entry>
<title>DRTVWR-558: Extend LLEventDispatcher::add() overloads.</title>
<updated>2023-07-13T16:49:09Z</updated>
<author>
<name>Nat Goodspeed</name>
<email>nat@lindenlab.com</email>
</author>
<published>2023-01-21T03:34:31Z</published>
<link rel='alternate' type='text/html' href='https://megapahit.org/viewer.git/commit/?id=2c894ecb25de044f5cb9c408c5264e5234b73983'/>
<id>urn:sha1:2c894ecb25de044f5cb9c408c5264e5234b73983</id>
<content type='text'>
Add LL::always_return&lt;T&gt;(), which takes a callable and variadic arguments. It
calls the callable with those arguments and, if the returned type is
convertible to T, converts it and returns it. Otherwise it returns T().
always_return() is generalized from, and supersedes,
LLEventDispatcher::ReturnLLSD.

Add LL::function_arity&lt;CALLABLE&gt;, which extends
boost::function_types::function_arity by reporting results for both
std::function&lt;CALLABLE&gt; and boost::function&lt;CALLABLE&gt;. Use for
LL::apply(function, LLSD array) as well as for LLEventDispatcher.

Make LLEventDispatcher::add() overloads uniformly distinguish between a
callable (whether non-static member function or otherwise) that accepts a
single LLSD parameter, versus any other signature. Accepting exactly one LLSD
parameter signals that the callable will accept the composite arguments LLSD
blob, instead of asking LLEventDispatcher to unpack the arguments blob into
individual arguments.

Support add(subclass method) overloads for arbitrary-parameters methods as
well as for (const LLSD&amp;) methods. Update tests accordingly: we need no longer
pass the boilerplate lambda instance getter that binds and returns 'this'.

Extract to the two LLEventDispatcher::make_invoker() overloads the LL::apply()
logic formerly found in ReturnLLSD.

Change lleventdispatcher_test.cpp tests from boost::bind(), which accepts
variadic arguments (even though it only passes a fixed set to the target
callable), to fixed-signature lambdas. This is because the revamped add()
overloads care about signature.

Add a test for a non-static method that accepts (const LLSD&amp;), in other words
the composite arguments LLSD blob, and likewise returns LLSD.

(cherry picked from commit 95b787f7d7226ee9de79dfc9816f33c8bf199aad)
</content>
</entry>
<entry>
<title>DRTVWR-558: Introduce LLDispatchListener batched requests.</title>
<updated>2023-07-13T16:49:08Z</updated>
<author>
<name>Nat Goodspeed</name>
<email>nat@lindenlab.com</email>
</author>
<published>2023-01-13T05:10:23Z</published>
<link rel='alternate' type='text/html' href='https://megapahit.org/viewer.git/commit/?id=d637229beeb3b7fa2bc7adb850ce9337b119037c'/>
<id>urn:sha1:d637229beeb3b7fa2bc7adb850ce9337b119037c</id>
<content type='text'>
Now the value of the incoming event's dispatch key may be an LLSD::String (as
before), a map or an array, as documented in the augmented Doxygen class
comments. LLDispatchListener will attempt multiple calls before sending a
reply.

(cherry picked from commit 7671b37285c6cdf1afcddb0019311a822c8a4dc5)
</content>
</entry>
<entry>
<title>DRTVWR-558: Break out new LLDispatchListener::call() method.</title>
<updated>2023-07-13T16:49:08Z</updated>
<author>
<name>Nat Goodspeed</name>
<email>nat@lindenlab.com</email>
</author>
<published>2023-01-12T15:49:01Z</published>
<link rel='alternate' type='text/html' href='https://megapahit.org/viewer.git/commit/?id=27f19826b6ef9b4af5db8613c44988b5c973618b'/>
<id>urn:sha1:27f19826b6ef9b4af5db8613c44988b5c973618b</id>
<content type='text'>
This captures logic we intend to reuse for forthcoming LLDispatchListener
batched request support.

(cherry picked from commit 3cb6d374cb76e4b00dc121255e8f5aa4e777fa27)
</content>
</entry>
<entry>
<title>DRTVWR-558: Add tests for LLDispatchListener functionality.</title>
<updated>2023-07-13T16:49:08Z</updated>
<author>
<name>Nat Goodspeed</name>
<email>nat@lindenlab.com</email>
</author>
<published>2023-01-10T22:38:01Z</published>
<link rel='alternate' type='text/html' href='https://megapahit.org/viewer.git/commit/?id=9553965ad661b2753d13fa9b414f529ad440000f'/>
<id>urn:sha1:9553965ad661b2753d13fa9b414f529ad440000f</id>
<content type='text'>
Refine the special case of calling a nullary target function from an (event)
method, notably via LLDispatchListener.

(cherry picked from commit edcc52a9f60b1ec9b8f53603d6e2676558d41294)
</content>
</entry>
</feed>
