Skip to content
Snippets Groups Projects
  1. Apr 07, 2021
  2. Apr 05, 2021
  3. Sep 10, 2020
  4. Jul 07, 2020
    • Nat Goodspeed's avatar
      DRTVWR-476, SL-13555: Don't crash if user closes viewer during login. · 87da08b1
      Nat Goodspeed authored
      Ever since February 2010, the body of the login coroutine function has been
      enclosed in try/catch (...), with an llerrs message to try to crash more
      informatively than the runtime's unhandled-exception termination. Over the
      years this evolved to LL_ERRS and then to CRASH_ON_UNHANDLED_EXCEPTION.
      
      This persisted despite the August 2016 addition of generic catch clauses in
      the LLCoros::toplevel() function to serve the same purpose, and despite the
      subsequent introduction of the LLCoros::Stop family of exceptions to
      deliberately throw into waiting coroutines on viewer shutdown.
      
      That's exactly what was happening. When the user closed the viewer while
      waiting for the response from login.cgi, the waiting operation threw
      LLCoros::Stopping, which was caught by that CRASH_ON_UNHANDLED_EXCEPTION,
      which crashed the viewer with LL_ERRS rather than propagating up to the
      toplevel() and cleanly terminating the coroutine.
      
      Change CRASH_ON_UNHANDLED_EXCEPTION() to LOG_UNHANDLED_EXCEPTION() and
      re-throw so toplevel() can handle.
      87da08b1
  5. Apr 03, 2020
  6. Mar 25, 2020
    • Nat Goodspeed's avatar
      DRTVWR-476, SL-12197: Don't throw Stopping from main coroutine. · 2a56ab44
      Nat Goodspeed authored
      The new LLCoros::Stop exception is intended to terminate long-lived coroutines
      -- not interrupt mainstream shutdown processing. Only throw it on an
      explicitly-launched coroutine.
      
      Make LLCoros::getName() (used by the above test) static. As with other LLCoros
      methods, it might be called after the LLCoros LLSingleton instance has been
      deleted. Requiring the caller to call instance() implies a possible need to
      also call wasDeleted(). Encapsulate that nuance into a static method instead.
      2a56ab44
    • Nat Goodspeed's avatar
      DRTVWR-476: Infrastructure to help manage long-lived coroutines. · 28a54c2f
      Nat Goodspeed authored
      Introduce LLCoros::Stop exception, with subclasses Stopping, Stopped and
      Shutdown. Add LLCoros::checkStop(), intended to be called periodically by any
      coroutine with nontrivial lifespan. It checks the LLApp status and, unless
      isRunning(), throws one of these new exceptions.
      
      Make LLCoros::toplevel() catch Stop specially and log forcible coroutine
      termination.
      
      Now that LLApp status matters even in a test program, introduce a trivial
      LLTestApp subclass whose sole function is to make isRunning() true.
      (LLApp::setStatus() is protected: only a subclass can call it.) Add LLTestApp
      instances to lleventcoro_test.cpp and lllogin_test.cpp.
      
      Make LLCoros::toplevel() accept parameters by value rather than by const
      reference so we can continue using them even after context switches.
      
      Make private LLCoros::get_CoroData() static. Given that we've observed some
      coroutines living past LLCoros destruction, making the caller call
      LLCoros::instance() is more dangerous than encapsulating it within a static
      method -- since the encapsulated call can check LLCoros::wasDeleted() first
      and do something reasonable instead. This also eliminates the need for both a
      const and non-const overload.
      
      Defend LLCoros::delete_CoroData() (cleanup function for fiber_specific_ptr for
      CoroData, implicitly called after coroutine termination) against calls after
      ~LLCoros().
      
      Add a status string to coroutine-local data, with LLCoro::setStatus(),
      getStatus() and RAII class TempStatus.
      
      Add an optional 'when' string argument to LLCoros::printActiveCoroutines().
      Make ~LLCoros() print the coroutines still active at destruction.
      28a54c2f
    • Nat Goodspeed's avatar
      SL-1968: Extend lllogin_test login-failed cases for new sync timing. · a9191a83
      Nat Goodspeed authored
      On login failure, LLLogin now tries to sync up with SLVersionChecker. It waits
      for up to 10 seconds before shrugging and giving up. Since that coroutine can
      now block for that long, make the llogin_test failure cases wait at least that
      long too.
      a9191a83
    • Anchor's avatar
      [DRTVWR-476] - compile error fix · 1ea42d88
      Anchor authored
      1ea42d88
    • Nat Goodspeed's avatar
      SL-793: Fix lllogin_test.cpp for new LLCoros implementation. · 101ab28f
      Nat Goodspeed authored
      Delete the test for SRV timeout: lllogin no longer issues an SRV query. That
      test only confuses the test program without exercising any useful paths in
      production code.
      
      As with other tests dating from the previous LLCoros implementation, we need a
      few llcoro::suspend() calls sprinkled in so that a fiber marked ready -- by
      fulfilling the future for which it is waiting -- gets a chance to run.
      
      Clear LLEventPumps between test functions.
      101ab28f
    • Nat Goodspeed's avatar
      SL-793: Use Boost.Fiber instead of the "dcoroutine" library. · 66981fab
      Nat Goodspeed authored
      Longtime fans will remember that the "dcoroutine" library is a Google Summer
      of Code project by Giovanni P. Deretta. He originally called it
      "Boost.Coroutine," and we originally added it to our 3p-boost autobuild
      package as such. But when the official Boost.Coroutine library came along
      (with a very different API), and we still needed the API of the GSoC project,
      we renamed the unofficial one "dcoroutine" to allow coexistence.
      
      The "dcoroutine" library had an internal low-level API more or less analogous
      to Boost.Context. We later introduced an implementation of that internal API
      based on Boost.Context, a step towards eliminating the GSoC code in favor of
      official, supported Boost code.
      
      However, recent versions of Boost.Context no longer support the API on which
      we built the shim for "dcoroutine." We started down the path of reimplementing
      that shim using the current Boost.Context API -- then realized that it's time
      to bite the bullet and replace the "dcoroutine" API with the Boost.Fiber API,
      which we've been itching to do for literally years now.
      
      Naturally, most of the heavy lifting is in llcoros.{h,cpp} and
      lleventcoro.{h,cpp} -- which is good: the LLCoros layer abstracts away most of
      the differences between "dcoroutine" and Boost.Fiber.
      
      The one feature Boost.Fiber does not provide is the ability to forcibly
      terminate some other fiber. Accordingly, disable LLCoros::kill() and
      LLCoprocedureManager::shutdown(). The only known shutdown() call was in
      LLCoprocedurePool's destructor.
      
      We also took the opportunity to remove postAndSuspend2() and its associated
      machinery: FutureListener2, LLErrorEvent, errorException(), errorLog(),
      LLCoroEventPumps. All that dual-LLEventPump stuff was introduced at a time
      when the Responder pattern was king, and we assumed we'd want to listen on one
      LLEventPump with the success handler and on another with the error handler. We
      have never actually used that in practice. Remove associated tests, of course.
      
      There is one other semantic difference that necessitates patching a number of
      tests: with "dcoroutine," fulfilling a future IMMEDIATELY resumes the waiting
      coroutine. With Boost.Fiber, fulfilling a future merely marks the fiber as
      ready to resume next time the scheduler gets around to it. To observe the test
      side effects, we've inserted a number of llcoro::suspend() calls -- also in
      the main loop.
      
      For a long time we retained a single unit test exercising the raw "dcoroutine"
      API. Remove that.
      
      Eliminate llcoro_get_id.{h,cpp}, which provided llcoro::get_id(), which was a
      hack to emulate fiber-local variables. Since Boost.Fiber has an actual API for
      that, remove the hack.
      
      In fact, use (new alias) LLCoros::local_ptr for LLSingleton's dependency
      tracking in place of llcoro::get_id().
      
      In CMake land, replace BOOST_COROUTINE_LIBRARY with BOOST_FIBER_LIBRARY. We
      don't actually use the Boost.Coroutine for anything (though there exist
      plausible use cases).
      66981fab
  7. Oct 04, 2018
    • Nat Goodspeed's avatar
      DRTVWR-474: Make login coroutine sync with updater process on failure. · 05068186
      Nat Goodspeed authored
      Specifically, introduce an LLEventMailDrop("LoginSync"). When the updater
      detects that an update is required, it will post to that rendezvous point.
      
      When login.cgi responds with login failure, make the login coroutine wait (a
      few seconds) for that ping from the updater.
      
      If we receive that ping and if it contains a "reply" key, make the fail.login
      listener respond to the updater with an indication of whether to proceed with
      update.
      
      If both login.cgi and the updater concur that an update is required, produce a
      new confirmation message for the user and then (once user responds) tell the
      updater to proceed. Otherwise, produce the usual login-failure message and
      tell the updater never mind.
      
      Introduce LLCoro::OverrideConsuming to provide temporary save/restore of the
      set_consuming() / get_consuming() flag. It's a good idea to set the consuming
      flag when retrieving data from an LLEventMailDrop.
      05068186
  8. Sep 07, 2018
  9. Sep 05, 2018
  10. May 24, 2017
  11. Mar 13, 2017
    • Nat Goodspeed's avatar
      DRTVWR-418: Use LLTempBoundListener to manage "mainloop" listener. · a33c5930
      Nat Goodspeed authored
      LLUpdaterServiceImpl binds its onMainLoop() listener method to the "mainloop"
      event so it can wake up periodically to recheck for updates. (Suggests maybe a
      smarter conventional callback-on-timer facility with a central queue, instead
      of every interested party intercepting *every* frame...)
      
      ~LLUpdaterServiceImpl() was calling LLEventPumps::instance() only to
      disconnect that listener, which was resurrecting the deleted LLEventPumps
      instance. Instead store an LLTempBoundListener in LLUpdaterServiceImpl, the
      conventional way to implicitly disconnect on destroy. Use its disconnect()
      method when explicit disconnection is desired.
      a33c5930
  12. Feb 28, 2017
  13. Aug 18, 2016
    • Nat Goodspeed's avatar
      MAINT-5011: Catch unhandled exceptions in LLCoros coroutines. · 4d10172d
      Nat Goodspeed authored
      Wrap coroutine call in try/catch in top-level coroutine wrapper function
      LLCoros::toplevel(). Distinguish exception classes derived from
      LLContinueError (log and continue) from all others (crash with LL_ERRS).
      
      Enhance CRASH_ON_UNHANDLED_EXCEPTIONS() and LOG_UNHANDLED_EXCEPTIONS() macros
      to accept a context string to supplement the log message. This lets us replace
      many places that called boost::current_exception_diagnostic_information() with
      LOG_UNHANDLED_EXCEPTIONS() instead, since the explicit calls were mostly to
      log supplemental information.
      
      Provide supplemental information (coroutine name, function parameters) for
      some of the previous LOG_UNHANDLED_EXCEPTIONS() calls. This information
      duplicates LL_DEBUGS() information at the top of these functions, but in a
      typical log file we wouldn't see the LL_DEBUGS() message.
      
      Eliminate a few catch (std::exception e) clauses: the information we get from
      boost::current_exception_diagnostic_information() in a catch (...) clause
      makes it unnecessary to distinguish.
      
      In a few cases, add a final 'throw;' to a catch (...) clause: having logged
      the local context info, propagate the exception to be caught by higher-level
      try/catch.
      
      In a couple places, couldn't resist reconciling indentation within a
      particular function: tabs where the rest of the function uses tabs, spaces
      where the rest of the function uses spaces.
      
      In LLLogin::Impl::loginCoro(), eliminate some confusing comments about an
      array of rewritten URIs that date back to a long-deleted implementation.
      4d10172d
    • Glenn Glazer's avatar
      c8c143e7
  14. Aug 17, 2016
  15. Aug 16, 2016
  16. Aug 15, 2016
  17. Jul 28, 2016
  18. Jul 27, 2016
  19. Jul 21, 2016
  20. 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
  21. Jul 14, 2016
  22. Jul 13, 2016
  23. Jul 11, 2016
Loading