summaryrefslogtreecommitdiff
path: root/indra/llcommon/llevents.cpp
AgeCommit message (Collapse)Author
2024-09-04Extract coroutine-aware synchronization primitives to new header.Nat Goodspeed
Changes on new main and changes on Lua project branch combined into a header circularity. Resolved by hoisting coroutine-aware synchronization primitives out to a new llcoromutex.h file in the `llcoro` namespace, rather than being literally members of the `LLCoros` class. But retained `using` declarations in `LLCoros` for backwards compatibility.
2024-08-28Ditch trailing spaces.Nat Goodspeed
2024-08-28Merge branch 'main' into release/luau-scripting.Nat Goodspeed
2024-07-18Make `LLEventPump::listen()` also accept new `LLAwareListener`.Nat Goodspeed
`listen()` still takes `LLEventListener`, a `callable(const LLSD&)`, but now also accepts `LLAwareListener`, a `callable(const LLBoundListener&, const LLSD&)`. This uses `boost::signals2::signal::connect_extended()`, which, when the signal is called, passes to a connected listener the `LLBoundListener` (aka `boost::signals2::connection`) representing its own connection. This allows a listener to disconnect itself when done. Internally, `listen_impl()` now always uses `connect_extended()`. When passed a classic `LLEventListener`, `listen()` wraps it in a lambda that ignores the passed `LLBoundListener`. `listen()` also now accepts `LLVoidListener`, and internally wraps it in a lambda that returns `false` on its behalf.
2024-06-12Fix whitespace pre-commit hook failuresBrad Linden
2024-05-10Fix latent access violation in ~LLEventPump() if LLEventPumps gone.Nat Goodspeed
Instead of making LLEventPumps an LLHandleProvider, and storing an LLHandle<LLEventPumps> in each LLEventPump instance, just make ~LLEventPump() query LLEventPumps::instanceExists() before calling instance().
2024-05-09Add "Timers" LLEventAPI, actually a LazyEventAPI, for LL::Timers.Nat Goodspeed
Rename LL::Timers::scheduleRepeating() to scheduleEvery().
2024-05-02#1354 Make coroutines use LLCoros::Mutex instead of LLMutex (#1356)RunitaiLinden
* #1354 Make coroutines use LLCoros::Mutex instead of LLMutex * #1354 Fix some more unsafe coroutine executions. * #1354 Implement changes requested by Nat
2024-04-24Merge 'main' into release/luau-scripting on promotion of Maint YZNat Goodspeed
2024-03-23Update sendReply(): accepting LLSD by value already copies it.Nat Goodspeed
2024-02-22 #include <iomanip> where std::quoted() is referenced.Nat Goodspeed
Remove where it isn't.
2024-02-22Add diagnostic logging to LLEventPumps::post().Nat Goodspeed
If post() can't find the requested pump, say so.
2024-01-04DRTVWR-589: Merge branch 'main' into DRTVWR-589Nat Goodspeed
2023-12-18Merge branch 'main' into DRTVWR-594-maint-YAndrey Lihatskiy
2023-11-23SL-17434 Crash clearing LLEventPumpsAndrey Kleshchev
We actively use event pumps's connections in threads, make sure nothing modifies list of connections during reset. And in case this doesn't fix the issue list affected pump before it crashes to have a better idea of what is going on.
2023-10-02DRTVWR-589: Add initial integration test for LLLUAmanager.Nat Goodspeed
The first test runs a Lua script that calls post_on(), listen_events() and await_event() to engage in LLEventPump handshakes with the test program. Make llluamanager.cpp testable by putting LL_TEST conditionals around lots of viewer-internals headers and the lua_function definitions that engage them. Since LuaListener::connect() is called by its constructor, make it a static method that explicitly accepts the lua_State* (instead of finding it as mState). Add that parameter to its two existing calls. Add a debug log message when LuaListener is destroyed. This surfaced the need to pass a no-op deleter when listen_events() constructs a LuaListener::ptr_t. When compiled for LL_TEST, make LuaListener::mReplyPump an LLEventLogProxyFor<LLEventStream> instead of a plain LLEventStream. For debugging purposes, add a type string "LLEventLogProxy" for LLEventPumps::make(). A make() call with this type will return an LLEventLogProxyFor<LLEventStream>.
2022-06-18DRTVWR-564: WIP: Add LazyEventAPI and tests. Tests don't yet pass.Nat Goodspeed
LazyEventAPI is a registrar that implicitly instantiates some particular LLEventAPI subclass on demand: that is, when LLEventPumps::obtain() tries to find an LLEventPump by the registered name. This leverages the new LLEventPumps::registerPumpFactory() machinery. Fix registerPumpFactory() to adapt the passed PumpFactory to accept TypeFactory parameters (two of which it ignores). Supplement it with unregisterPumpFactory() to support LazyEventAPI instances with lifespans shorter than the process -- which may be mostly test programs, but still a hole worth closing. Similarly, add unregisterTypeFactory(). A LazyEventAPI subclass takes over responsibility for specifying the LLEventAPI's name, desc, field, plus whatever add() calls will be needed to register the LLEventAPI's operations. This is so we can (later) enhance LLLeapListener to consult LazyEventAPI instances for not-yet-instantiated LLEventAPI metadata, as well as enumerating existing LLEventAPI instances. The trickiest part of this is capturing calls to the various LLEventDispatcher::add() overloads in such a way that, when the LLEventAPI subclass is eventually instantiated, we can replay them in the new instance. LLEventAPI acquires a new protected constructor specifically for use by a subclass registered by a companion LazyEventAPI. It accepts a const reference to LazyEventAPIParams, intended to be opaque to the LLEventAPI subclass; the subclass must declare a constructor that accepts and forwards the parameter block to the new LLEventAPI constructor. The implementation delegates to the existing LLEventAPI constructor, plus it runs deferred add() calls. LLDispatchListener now derives from LLEventStream instead of containing it as a data member. The reason is that if LLEventPumps::obtain() implicitly instantiates it, LLEventPumps's destructor will try to destroy it by deleting the LLEventPump*. If the LLEventPump returned by the factory function is a data member of an outer class, that won't work so well. But if LLDispatchListener (and by implication, LLEventAPI and any subclass) is derived from LLEventPump, then the virtual destructor will Do The Right Thing. Change LLDispatchListener to *not* allow tweaking the LLEventPump name. Since the overwhelming use case for LLDispatchListener is LLEventAPI, accepting but silently renaming an LLEventAPI subclass would ensure nobody could reach it. Change LLEventDispatcher's use of std::enable_if to control the set of add() overloads available for the intended use cases. Apparently this formulation is just as functional at the method declaration point, while avoiding the need to restate the whole enable_if expression at the method definition point. Add lazyeventapi_test.cpp to exercise.
2022-06-15DRTVWR-564: WIP: add LLEventPumps::registerPumpFactory()Nat Goodspeed
and registerTypeFactory(). Untested. This will support registering just-in-time LLEventAPI instances, instantiated on demand.
2021-05-28SL-15093 Crash nanov2_free_to_blockAndrey Kleshchev
Superficially crash happens in disconnect() inside signal's deconstructor. Manual cleanup should help figuring out if crash happens due to named or anonymous listeners
2020-03-25DRTVWR-476: Make ~LLEventPumps() call reset() on its way out.Nat Goodspeed
~LLEventPumps() deletes every LLEventPump instance it created itself. However, many classes themselves contain LLEventPump subclass instances. These are registered with LLEventPumps without it managing their lifespan. But LLEventPump::reset() frees the LLStandardSignal aka boost::signals2::signal instance owned by the LLEventPump, perforce disconnecting all current listeners and disabling the LLEventPump. Even though the instance still exists, if someone subsequently calls post(), nothing will happen -- which is better than control trying to reach a method of a deleted object.
2020-03-25DRTVWR-476: Eliminate static LLEventPump factory maps.Nat Goodspeed
Having a map from std::string to a factory function returning LLEventPump* is a cool idea, especially since you could statically populate such a map with string literals and little lambdas. Unfortunately, static initialization of any data is a bad idea when control can reach consuming code before that module's static data are constructed. Since LLEventPumps is already an LLSingleton, it's simple enough to make its map non-static and initialize it in the constructor. But another recent static factory-function map was introduced in llleaplistener.cpp to support the LLLeapListener::newpump() operation. That involves no LLSingletons. Introduce LLEventPumps::make(name, tweak, type) to instantiate an LLEventPump subclass of the specified type with specified (name, tweak) parameters. Instances returned by make() are owned by LLEventPumps, as with obtain(). Introduce LLEventPumps::BadType exception for when the type string isn't recognized. LLEventPumps::obtain() can then simply call make() when the specified instance name doesn't already exist. The configuration data used internally by obtain() becomes { string instance name, string subclass name }. Although this too is currently initialized in the LLEventPumps constructor, migrating it to a configuration file would now be far more straightforward than before. LLLeapListener::newpump(), too, can call LLEventPumps::make() with the caller-specified type string. This eliminates that static factory map. newpump() must catch BadType and report the error back to its invoker. Given that the LLEventPump subclass instances returned by make() are owned by LLEventPumps rather than LLLeapListener, there is no further need for the LLLeapListener::mEventPumps ptr_map, which was used only to manage lifetime. Also remove LLLeapListener's "killpump" operation since LLEventPumps provides no corresponding functionality.
2020-03-25DRTVWR-476: Kill LLEventQueue, per-frame LLEventPump::flush() calls.Nat Goodspeed
No one uses LLEventQueue to defer posted events until the next mainloop tick -- and with LLCoros moving to Boost.Fiber, cross-coroutine event posting works that way anyway, making LLEventQueue pretty unnecessary. The static RegisterFlush instance in llevents.cpp was used to call LLEventPumps::flush() once per mainloop tick, which in turn called flush() on every registered LLEventPump. But the only reason for that mechanism was to support LLEventQueue. In fact, when LLEventMailDrop overrode its flush() method for something quite different, it was startling to find that the new flush() override was being called once per frame -- which caused at least one fairly mysterious bug. Remove RegisterFlush. Both LLEventPumps::flush() and LLEventPump::flush() remain for now, though intended usage is unclear. Eliminating LLEventQueue means we must at least repurpose LLEventPumps::mQueueNames, a map intended to make LLEventPumps::obtain() instantiate an LLEventQueue rather than the default LLEventPump. Replace it with mFactories, a map from desired instance name to a callable returning LLEventPump*. New map initialization syntax plus lambda support allows us to populate that map at compile time with little lambdas returning the correct subclass instance. Similarly, LLLeapListener::newpump() used to check the ["type"] entry in the LLSD request specifically for "LLEventQueue". Introduce another such map in llleaplistener.cpp for potential future extensibility. Eliminate the LLEventQueue-specific test.
2020-03-25DRTVWR-476: Introduce LLEventMailDrop::discard() (instead of flush()).Nat Goodspeed
Overriding virtual LLEventPump::flush() for the semantic of discarding LLEventMailDrop's queued events turns out not to be such a great idea, because LLEventPumps::flush(), which calls every registered LLEventPump's flush() method, is called every mainloop tick. The first time we hit a use case in which we expected LLEventMailDrop to hold queued events across a mainloop tick, we were baffled that they were never delivered. Moving that logic to a separate method specific to LLEventMailDrop resolves that problem. Naming it discard() clarifies its intended functionality.
2020-03-25SL-793: Add LLEventPumps::clear() method to disconnect all listeners.Nat Goodspeed
This is like the existing reset() method, except that reset() is specifically intended for shutdown: it disables every existing LLEventPump in such a way that it cannot be subsequently reused. (The original idea was to disconnect listeners in DLLs unloaded at shutdown.) clear() forcibly disconnects all existing listeners, but leaves LLEventPumps ready for reuse. This is useful (e.g.) for test programs to reset the state of LLEventPumps between individual test functions.
2018-09-27DRTVWR-474: Make LLEventMailDrop pass all saved events to listener.Nat Goodspeed
Previously, LLEventMailDrop would send only the first queued event to a newly-connected listener. If you wanted to flush all queued events, you'd have to "pump" the queue by repeatedly disconnecting and reconnecting -- with no good way to know when you'd caught up. The new behavior makes LLEventMailDrop resemble a multi-valued future: a rendezvous between producer and consumer that, once connected, pushes values rather than requiring them to be pulled (as with a simple queue) -- regardless of the relative order in which post() and listen() are called.
2017-10-11Automated merge with ssh://bitbucket.org/lindenlab/viewer-releaseNat Goodspeed
2017-09-19MAINT-7820 Fixed crash in LLEventPumpandreykproductengine
2017-03-13DRTVWR-418: Make LLEventPumps an LLHandleProvider for LLEventPump.Nat Goodspeed
LLEventPump's destructor was using LLEventPumps::instance() to unregister the LLEventPump instance from LLEventPumps. Evidently, though, there are lingering LLEventPump instances that persist even after the LLSingletonBase::deleteAll() call destroys the LLEventPumps LLSingleton instance. These were resurrecting LLEventPumps -- pointlessly, since a newly-resurrected LLEventPumps instance can have no knowledge of the LLEventPump instance! Unregistering is unnecessary! What we want is a reference we can bind into each LLEventPump instance that allows us to safely test whether the LLEventPumps instance still exists. LLHandle is exactly that. Make LLEventPumps an LLHandleProvider and bind its LLHandle in each LLEventPump's constructor; then the destructor can unregister only when LLEventPumps still exists.
2016-10-10Merged in lindenlab/viewer-releaseAndreyL ProductEngine
2016-08-17MAINT-5011: Use LLTHROW() instead of plain BOOST_THROW_EXCEPTION().Nat Goodspeed
A level of preprocessor indirection lets us later change the implementation if desired.
2016-07-19MAINT-5011: Introduce LLException base class for viewer exceptions.Nat Goodspeed
This also introduces LLContinueError for exceptions which should interrupt some part of viewer processing (e.g. the current coroutine) but should attempt to let the viewer session proceed. Derive all existing viewer exception classes from LLException rather than from std::runtime_error or std::logic_error. Use BOOST_THROW_EXCEPTION() rather than plain 'throw' to enrich the thrown exception with source file, line number and containing function.
2016-06-24MAINT-6521: A compare against a static const empty string causes segfault in ↵Rider Linden
integration tests on Mac and Linux. Use empty() test instead.
2016-06-23MAINT-6521: Allow anonymous connections to bypass the dependency and order ↵Rider Linden
tracking.
2016-04-04merge with 4.0.3-releaseOz Linden
2015-12-22MAINT-5976: Removed temp code to simulate Nat's fix. Now redundant.Rider Linden
2015-12-17MAINT-5977: Check get_consuming() as well as listener return when draining ↵Rider Linden
queue.
2015-12-17MAINT-5977: Finish implementation of MailBox event pump type for guaranteed ↵Rider Linden
delivery
2015-12-17MAINT-5976: Adding MailDrop type event Queuerider
2015-12-04Initial changes for Vivox/Azumarill merge. Lots of temporary code and ↵Rider Linden
conditional compile switches. Begin switch from statemachine to coroutine.
2015-11-10remove execute permission from many files that should not have itOz Linden
2013-06-05merge with viewer-releaseRichard Linden
2013-03-29Update Mac and Windows breakpad builds to latestGraham Madarasz
2012-12-06SH-3406 WIP convert fast timers to lltrace systemRichard Linden
improved LLUnit compile time errors removed cassert in favor of llstatic_assert
2012-02-01converted a bunch of narrowing implicit conversions to explicitRichard Linden
2011-08-30CHOP-763: make sendReply() treat replyKey as optional.Nat Goodspeed
It's not worth bothering to tweak reply LLSD or attempt to send it if the incoming request has no replyKey, in effect not requesting a reply. This supports LLEventAPI operations for which the caller might or might not care about a reply, invoked using either send() (fire and forget) or request() (send request, wait for response). This logic should be central, instead of having to perform that test in every caller that cares. The major alternative would have been to treat missing replyKey as an error (whether LL_ERRS or exception). But since there's already a mechanism by which an LLEventAPI operation method can stipulate its replyKey as required, at this level we can let it be optional.
2011-02-18Introduce and use new sendReply() function for LLEventAPI methods.Nat Goodspeed
Each LLEventAPI method that generates a reply needs to extract the name of the reply LLEventPump from the request, typically from a ["reply"] key, copy the ["reqid"] value from request to reply, locate the reply LLEventPump and send the enriched reply object. Encapsulate in sendReply() function before we proliferate doing all that by hand too many more times.
2010-12-13permit flush when disabled.Andrew A. de Laix
2010-12-10fix possible crash on shutdown in event queue flush.Andrew A. de Laix
2010-12-10fix crash if posting event during shutdown.Andrew A. de Laix
2010-08-13Change license from GPL to LGPL (version 2.1)Oz Linden