Skip to content
Snippets Groups Projects
  1. Mar 25, 2020
    • Nat Goodspeed's avatar
      DRTVWR-476: Make ~LLEventPumps() call reset() on its way out. · aea1e469
      Nat Goodspeed authored
      ~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.
      aea1e469
    • Nat Goodspeed's avatar
      DRTVWR-476: Eliminate static LLEventPump factory maps. · 95a218fc
      Nat Goodspeed authored
      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.
      95a218fc
    • Nat Goodspeed's avatar
      DRTVWR-476: Kill LLEventQueue, per-frame LLEventPump::flush() calls. · 79a3e391
      Nat Goodspeed authored
      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.
      79a3e391
    • Nat Goodspeed's avatar
      DRTVWR-476: Introduce LLEventMailDrop::discard() (instead of flush()). · 6805e82a
      Nat Goodspeed authored
      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.
      6805e82a
    • Nat Goodspeed's avatar
      SL-793: Add LLEventPumps::clear() method to disconnect all listeners. · 0c32c98f
      Nat Goodspeed authored
      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.
      0c32c98f
  2. Sep 27, 2018
    • Nat Goodspeed's avatar
      DRTVWR-474: Make LLEventMailDrop pass all saved events to listener. · ec6487f3
      Nat Goodspeed authored
      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.
      ec6487f3
  3. Sep 19, 2017
  4. Mar 13, 2017
    • Nat Goodspeed's avatar
      DRTVWR-418: Make LLEventPumps an LLHandleProvider for LLEventPump. · c1458713
      Nat Goodspeed authored
      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.
      c1458713
  5. Aug 17, 2016
  6. Jul 19, 2016
    • Nat Goodspeed's avatar
      MAINT-5011: Introduce LLException base class for viewer exceptions. · 9c49a6c9
      Nat Goodspeed authored
      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.
      9c49a6c9
  7. Jun 24, 2016
  8. Jun 23, 2016
  9. Dec 22, 2015
  10. Dec 17, 2015
  11. Dec 04, 2015
  12. Nov 10, 2015
  13. Jun 05, 2013
  14. Jun 04, 2013
  15. Jun 01, 2013
  16. Mar 29, 2013
  17. Dec 06, 2012
  18. Feb 01, 2012
  19. Aug 30, 2011
    • Nat Goodspeed's avatar
      CHOP-763: make sendReply() treat replyKey as optional. · 5fb224bb
      Nat Goodspeed authored
      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.
      5fb224bb
  20. Feb 18, 2011
    • Nat Goodspeed's avatar
      Introduce and use new sendReply() function for LLEventAPI methods. · 4ef02bc1
      Nat Goodspeed authored
      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.
      4ef02bc1
  21. Dec 13, 2010
  22. Dec 10, 2010
  23. Oct 13, 2010
  24. Sep 21, 2010
  25. Aug 13, 2010
  26. Nov 30, 2009
    • Nat Goodspeed's avatar
      DEV-43463: Keep LLEventPump's LLStandardSignal alive during post() · 7b6ddb41
      Nat Goodspeed authored
      Replace LLEventPump's boost::scoped_ptr<LLStandardSignal> with
      boost::shared_ptr. Take a local stack copy of that shared_ptr in post()
      methods, and invoke the signal through that copy. This guards against scenario
      in which LLEventPump gets destroyed during signal invocation. (See Jira for
      details.) Re-enable Mani's test case that used to crash.
      Introduce ll_template_cast<> to allow a template function to recognize a
      parameter of a particular type.
      Introduce LLListenerWrapper mechanism to support wrapper objects for
      LLEventPump listeners. You instantiate an LLListenerWrapper subclass object
      inline in the listen() call (typically with llwrap<>), passing it the real
      listener, trusting it to forward the eventual call.
      Introduce prototypical LLCoutListener and LLLogListener subclasses for
      illustrative and diagnostic purposes. Test that LLLogListener doesn't block
      recognizing LLEventTrackable base class bound into wrapped listener.
      7b6ddb41
  27. Oct 21, 2009
  28. Sep 24, 2009
  29. Aug 06, 2009
  30. Jun 04, 2009
  31. May 27, 2009
    • Nat Goodspeed's avatar
      DEV-31979: Introduce LLReqID, a class to help individual event API listeners · f910157c
      Nat Goodspeed authored
      implement the ["reqid"] convention. This convention dictates that a response
      LLSD from each such API should contain a ["reqid"] key whose value echoes the
      ["reqid"] value, if any, in the request LLSD.
      Add LLReqID support to LLAresListener's "rewriteURI" service, LLSDMessage,
      LLCapabilityListener and LLXMLRPCListener.
      f910157c
  32. May 11, 2009
  33. May 08, 2009
Loading