Skip to content
Snippets Groups Projects
  1. Mar 25, 2020
    • Nat Goodspeed's avatar
      DRTVWR-476: make printActiveCoroutines() output slightly clearer. · 0756885e
      Nat Goodspeed authored
      For the main coroutine on each thread, show the 'main0' (or whatever) name
      instead of the empty-string name.
      0756885e
    • Nat Goodspeed's avatar
      DRTVWR-476: Make llcoro::logname() distinguish different threads. · 39e7b483
      Nat Goodspeed authored
      Actually, introduce static LLCoros::logname() and make the namespaced free
      function an alias for that.
      
      Because CoroData is a subclass of LLInstanceTracker with a key, every instance
      requires a distinct key. That conflicts with our "getName() returns empty
      string for default coroutine on thread" convention. Introduce a new CoroData
      constructor, specifically for the default coroutine on each thread, that
      initializes the getName() name to empty string while providing a distinct
      "mainN" key. Make get_CoroData() use that new constructor for its thread_local
      instance, passing an atomic<int> incremented each time we initialize one for a
      new thread.
      
      Then LLCoros::logname() returns either the getName() name or the key.
      39e7b483
    • Nat Goodspeed's avatar
    • 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: Keep coroutine-local data on toplevel()'s stack frame. · 9008124d
      Nat Goodspeed authored
      Instead of heap-allocating a CoroData instance per coroutine, storing the
      pointer in a ptr_map and deleting it from the ptr_map once the
      fiber_specific_ptr for that coroutine is cleaned up -- just declare a stack
      instance on the top-level stack frame, the simplest C++ lifespan management.
      Derive CoroData from LLInstanceTracker to detect potential name collisions and
      to enumerate instances.
      
      Continue registering each coroutine's CoroData instance in our
      fiber_specific_ptr, but use a no-op deleter function.
      
      Make ~LLCoros() directly pump the fiber scheduler a few times, instead of
      having a special "LLApp" listener.
      9008124d
    • Nat Goodspeed's avatar
    • Nat Goodspeed's avatar
      DRTVWR-476: Pump coroutines a few more times when we start quitting. · cbf146f2
      Nat Goodspeed authored
      By the time "LLApp" listeners are notified that the app is quitting, the
      mainloop is no longer running. Even though those listeners do things like
      close work queues and inject exceptions into pending promises, any coroutines
      waiting on those resources must regain control before they can notice and shut
      down properly. Add a final "LLApp" listener that resumes ready coroutines a
      few more times.
      
      Make sure every other "LLApp" listener is positioned before that new one.
      cbf146f2
    • 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
    • Anchor's avatar
      [DRTVWR-476] - compile error fix · 243b1115
      Anchor authored
      243b1115
    • 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
  2. Aug 06, 2019
  3. Jun 22, 2018
  4. May 14, 2018
  5. May 30, 2018
  6. Oct 05, 2017
  7. Nov 15, 2016
    • Nat Goodspeed's avatar
      DRTVWR-418: Fold windows64 into windows platform with new autobuild. · 6c7a9728
      Nat Goodspeed authored
      autobuild 1.1 now supports expanding $variables within a config file --
      support that was explicitly added to address this very problem. So now the
      windows platform in autobuild.xml uses $AUTOBUILD_ADDRSIZE,
      $AUTOBUILD_WIN_VSPLATFORM and $AUTOBUILD_WIN_CMAKE_GEN, which should handle
      most of the deltas between the windows platform and windows64.
      
      This permits removing the windows64 platform definition from autobuild.xml.
      
      The one remaining delta between the windows64 and windows platform definitions
      was -DLL_64BIT_BUILD=TRUE. But we can handle that instead by checking
      ADDRESS_SIZE. Change all existing references to WORD_SIZE to ADDRESS_SIZE
      instead, and set ADDRESS_SIZE to $AUTOBUILD_ADDRSIZE. Change the one existing
      LL_64BIT_BUILD reference to test (ADDRESS_SIZE EQUAL 64) instead.
      6c7a9728
  8. Sep 06, 2016
    • Nat Goodspeed's avatar
      MAINT-5232: Ensure that llcoro::get_id() returns distinct values. · a601c559
      Nat Goodspeed authored
      Until now, the "main coroutine" (the initial context) of each thread left
      LLCoros::Current() NULL. The trouble with that is that llcoro::get_id()
      returns that CoroData* as an opaque token, and we want distinct values for
      every stack in the process. That would not be true if the "main coroutine" on
      thread A returned the same value (NULL) as the "main coroutine" on thread B,
      and so forth. Give each thread's "main coroutine" a dummy heap CoroData
      instance of its own.
      a601c559
    • Oz Linden's avatar
      downgrade spammy LLCoros logging to DEBUG · 72f4c720
      Oz Linden authored
      72f4c720
  9. Sep 03, 2016
    • Nat Goodspeed's avatar
      MAINT-5232: Add LLCoros::get_id() to identify the running coroutine. · f931f6ef
      Nat Goodspeed authored
      Change the module-static thread_specific_ptr to a function-static
      thread_specific_ptr so it will be initialized on demand -- since LLSingleton
      will need to rely on get_id(). Note that since LLCoros isa LLSingleton, we
      must take great care to avoid circularity.
      
      Introduce a private helper class LLCoros::Current to obtain and bind that
      thread_specific_ptr. Change all existing internal references from the static
      thread_specific_ptr to the new Current helper class.
      f931f6ef
  10. Aug 26, 2016
  11. Aug 25, 2016
  12. 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
  13. Jul 05, 2016
  14. Jun 28, 2016
  15. Dec 16, 2015
  16. Nov 20, 2015
  17. Nov 10, 2015
  18. Jul 10, 2015
  19. Jul 07, 2015
  20. Jul 02, 2015
    • Nat Goodspeed's avatar
      MAINT-5357: Introduce and populate llcoro:: namespace. · f90023fc
      Nat Goodspeed authored
      To date, the coroutine helper functions in lleventcoro.h have been in the
      global namespace. Migrate them into llcoro namespace, and fix references.
      Specifically, LLVoidListener => llcoro::VoidListener, and voidlistener(),
      postAndWait(), both waitForEventOn(), postAndWait2(), errorException() and
      errorLog() have been moved into llcoro.
      Also migrate new LLCoros::get_self() and Suspending to llcoro:: namespace.
      While at it, I realized that -- having converted several lleventcoro.h
      functions from templates (for arbitrary 'self' parameter type) to ordinary
      functions, having moved them from lleventcoro.h to lleventcoro.cpp, we can now
      migrate their helpers from lleventcoro.h to lleventcoro.cpp as well. This
      eliminates the need for the LLEventDetail namespace; the relevant helpers are
      now in an anonymous namespace in the .cpp file: listenerNameForCoro(),
      storeToLLSDPath(), WaitForEventOnHelper and wfeoh().
      f90023fc
  21. Jul 01, 2015
  22. Jun 05, 2013
  23. Jun 04, 2013
  24. Jun 01, 2013
  25. May 23, 2013
    • Nat Goodspeed's avatar
      MAINT-2724: Make viewer explicitly set coroutine stack size. · 3be79d53
      Nat Goodspeed authored
      Introduce LLCoros::setStackSize(), with a compile-time default value we hope
      we never have to use. Make LLAppViewer call it with the value of the new
      settings variable CoroutineStackSize as soon as we've read settings files.
      (While we're at it, notify interested parties that we've read settings files.)
      Give CoroutineStackSize a default value four times the previous default stack
      size. Make LLCoros::launch() pass the saved stack size to each new coroutine
      instance.
      Re-enable lleventcoro integration test. Use LLSDMap() construct rather than
      LLSD::insert(), which used to return the modified object but is now void.
      3be79d53
Loading