Skip to content
Snippets Groups Projects
  1. Mar 25, 2020
    • Ankur Ahlawat's avatar
      [DRTVWR-476] - update colladodom · 9bc3da0e
      Ankur Ahlawat authored
      9bc3da0e
    • Ankur Ahlawat's avatar
      [DRTVWR-476] - updated googlemock · 9c44e39f
      Ankur Ahlawat authored
      9c44e39f
    • Ankur Ahlawat's avatar
      [DRTVWR-476] - update boost · baa19813
      Ankur Ahlawat authored
      baa19813
    • Anchor's avatar
      [DRTVWR-476] - fix msvc version · e335fde0
      Anchor authored
      e335fde0
    • Ankur Ahlawat's avatar
      [DRTVWR-476] - update googlemock · 5db924ce
      Ankur Ahlawat authored
      5db924ce
    • Ankur Ahlawat's avatar
      [DRTVWR-476] - updated libpng · ca0cc135
      Ankur Ahlawat authored
      ca0cc135
    • Ankur Ahlawat's avatar
      2f1a48e0
    • Anchor's avatar
      [DRTVWR-476] - update autobuild packages · f0654f69
      Anchor authored
      f0654f69
    • Nat Goodspeed's avatar
    • Nat Goodspeed's avatar
      DRTVWR-476: Eliminate std::mem_fun1() special case for Windows. · e9c667af
      Nat Goodspeed authored
      We used to have to use #if LL_WINDOWS logic to pass std::mem_fun1() to
      llbind2nd() instead of std::mem_fun() elsewhere. VS 2017 no longer supports
      std::mem_fun1(), which means we can eliminate the special case for Windows.
      e9c667af
    • Nat Goodspeed's avatar
      DRTVWR-476: Fix _open_osfhandle() param from long to intptr_t. · f71c71fe
      Nat Goodspeed authored
      The Microsoft _open_osfhandle() opens a HANDLE to produce a C-style int file
      descriptor suitable for passing to _fdopen(). We used to cast the HANDLEs
      returned by GetStdHandle() to long to pass to _open_osfhandle(). Since HANDLE
      is an alias for a pointer, this no longer works.
      
      Fortunately _open_osfhandle() now accepts intptr_t, so we can change the
      relevant GetStdHandle() calls. (But why not simply accept HANDLE in the first
      place?)
      f71c71fe
    • Nat Goodspeed's avatar
      DRTVWR-476: Fix glVertexAttrib{IPointer,PointerARB}() OpenGL calls. · 30fa2496
      Nat Goodspeed authored
      VS 2017 complains about the same thing that clang does: casting S32 to GLvoid*
      can't possibly produce a valid pointer value because S32 can't fit a whole
      64-bit pointer. To appease it, not only must we use reinterpret_cast, but we
      must first cast S32 to intptr_t and then reinterpret_cast THAT.
      30fa2496
    • Nat Goodspeed's avatar
      DRTVWR-476: Explicitly cast 64-bit NaN constant to F32 as needed. · c80c5fa5
      Nat Goodspeed authored
      VS 2017 was complaining about truncating the value.
      c80c5fa5
    • Nat Goodspeed's avatar
      DRTVWR-476: Eliminate unnecessary typedefs from struct, enum decls. · daeeab36
      Nat Goodspeed authored
      With VS 2017, these produced fatal warnings.
      daeeab36
    • Nat Goodspeed's avatar
      DRTVWR-476: Remove throw(T) from operator new(), operator delete(). · 25a65844
      Nat Goodspeed authored
      llcorehttp's test_allocator.{h,cpp} overrides global operator new(), operator
      new[](), operator delete() and operator delete[](). The two operator new()
      functions used to be declared with throw(std::bad_alloc). Worse, for VS 2013
      and previous, we needed _THROW0() and _THROW1(std::bad_alloc) instead,
      requiring #if logic.
      
      But with dynamic throw declarations deprecated, we must actually remove those.
      That obviates the THROW_BAD_ALLOC() / THROW_NOTHING() workarounds in
      test_allocator.cpp.
      25a65844
    • Nat Goodspeed's avatar
      DRTVWR-476: Use OpenSSL API suitable for 64-bit pointers. · 3753dbd5
      Nat Goodspeed authored
      In three different places we use the same pattern: an ssl_thread_id_callback()
      function (a static member of LLCrashLogger, in that case) that used to be
      passed to CRYPTO_set_id_callback() and therefore returned an unsigned long
      representing the ID of the current thread.
      
      But GetCurrentThread() is a HANDLE, an alias for a pointer, and you can't
      uniquely cram a 64-bit pointer into an unsigned long.
      
      Fortunately OpenSSL has a more modern API for retrieving thread ID. Pass
      each ssl_thread_id_callback() function to CRYPTO_THREADID_set_callback()
      instead, converting it to accept CRYPTO_THREADID* and call
      CRYPTO_THREADID_set_pointer() or CRYPTO_THREADID_set_numeric() as appropriate().
      3753dbd5
    • Nat Goodspeed's avatar
      DRTVWR-476: Eliminate snprintf_hack::snprintf(). Use MS snprintf(). · cbbe655f
      Nat Goodspeed authored
      https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/snprintf-snprintf-snprintf-l-snwprintf-snwprintf-l?view=vs-2017
      "Beginning with the UCRT in Visual Studio 2015 and Windows 10, snprintf is no
      longer identical to _snprintf. The snprintf function behavior is now C99
      standard compliant."
      
      In other words, VS 2015 et ff. snprintf() now promises to nul-terminate the
      buffer even in the overflow case, which is what snprintf_hack::snprintf() was
      for.
      
      This removal was motivated by ambiguous-call errors generated by VS 2017 for
      library snprintf() vs. snprintf_hack::snprintf().
      cbbe655f
    • Nat Goodspeed's avatar
      DRTVWR-476: Update Copy3rdPartyLibs.cmake for VS 2017 version. · e849dfb9
      Nat Goodspeed authored
      Also, on Windows, put build output into
      build-vc$AUTOBUILD_VSVER-$AUTOBUILD_ADDRSIZE instead of hard-coding
      build-vc120-$AUTOBUILD_ADDRSIZE.
      e849dfb9
    • Nat Goodspeed's avatar
      SL-11215: Add release notes URLs to update-related notifications. · bf999f2f
      Nat Goodspeed authored
      Add code to login-fail handler to provide release notes URL from
      SLVersionChecker handshake event.
      bf999f2f
    • Nat Goodspeed's avatar
      1846234c
    • Nat Goodspeed's avatar
      SL-11216: Try to pacify VS 2013. · 8961be78
      Nat Goodspeed authored
      8961be78
    • Nat Goodspeed's avatar
      SL-11216: To display release notes, listen on "relnotes" LLEventPump. · 31d9930a
      Nat Goodspeed authored
      Now, when the viewer decides it's appropriate to display release notes on the
      login screen, wait for SLVersionChecker to post the release-notes URL before
      opening the web floater.
      31d9930a
    • Nat Goodspeed's avatar
      SL-11216: getViewerInfo() calls LLVersionInfo::getReleaseNotes(). · 15418f99
      Nat Goodspeed authored
      Make LLAppViewer retrieve release notes from LLVersionInfo, rather than
      synthesizing the release-notes URL itself based on the viewer version string.
      15418f99
    • Nat Goodspeed's avatar
      SL-11216: Add a "getStateTable" op to "LLStartUp" listener. · 7fbbd4b7
      Nat Goodspeed authored
      getStateTable returns a list of the EStartupState symbolic names, implicitly
      mapping each to its index (its enum numeric value).
      7fbbd4b7
    • Nat Goodspeed's avatar
      SL-11216: Allow llsd::drill() to accept LLSD() as (empty) path. · e6a9523d
      Nat Goodspeed authored
      Before this change, you had to literally pass LLSD::emptyArray() to get no-op
      behavior.
      e6a9523d
    • Nat Goodspeed's avatar
      SL-11216: Introduce LLVersionInfo::getReleaseNotes() method. · 378e4fae
      Nat Goodspeed authored
      The default string returned by getReleaseNotes() is empty. It must be set by
      posting the relevant release-notes URL string to a new LLEventMailDrop
      instance named "relnotes".
      
      Add unique_ptr<LLEventMailDrop> and unique_ptr<LLStoreListener<std::string>>
      to LLVersionInfo -- using unique_ptr to leave those classes opaque to
      header-file consumers. Introduce an out-of-line destructor to handle the
      unique_ptr<opaque> idiom.
      
      Initialize the LLEventMailDrop with the desired name; initialize the
      LLStoreListener with that LLEventMailDrop and the data member returned by
      getReleaseNotes().
      378e4fae
    • Nat Goodspeed's avatar
      SL-11216: Introduce generic LLStoreListener<T> to capture event data. · 8bb8d7e5
      Nat Goodspeed authored
      LLStoreListener is an adapter initialized with a reference to an LLEventPump
      on which to listen, a reference to a variable into which to store received
      data, and an optional llsd::drill() path to extract desired data from each
      event received on the subject LLEventPump.
      
      In effect, LLStoreListener is like a miniature LLEventAPI whose only operation
      is to store to its destination variable.
      8bb8d7e5
    • Nat Goodspeed's avatar
      SL-11216: Add llsd::drill() function to drill into an LLSD blob. · a2379d68
      Nat Goodspeed authored
      We include both const and non-const overloads. The latter returns LLSD&, so
      you can assign to the located element.
      
      In fact we already implemented the non-const logic in a less public form as
      storeToLLSDPath() in lleventcoro.cpp. Reimplement the latter to use the new
      llsd::drill() function.
      a2379d68
    • Nat Goodspeed's avatar
      SL-11216: Convert LLVersionInfo to an LLSingleton. · 5a260e0c
      Nat Goodspeed authored
      This changeset is meant to exemplify how to convert a "namespace" class whose
      methods are static -- and whose data are module-static -- to an LLSingleton.
      LLVersionInfo has no initClass() or cleanupClass() methods, but the general
      idea is the same.
      
      * Derive the class from LLSingleton<T>:
        class LLSomeSingleton: public LLSingleton<LLSomeSingleton> { ... };
      * Add LLSINGLETON(LLSomeSingleton); in the private section of the class. This
        usage implies a separate LLSomeSingleton::LLSomeSingleton() definition, as
        described in indra/llcommon/llsingleton.h.
      * Move module-scope data in the .cpp file to non-static class members. Change
        any sVariableName to mVariableName to avoid being outright misleading.
      * Make static class methods non-static. Remove '//static' comments from method
        definitions as needed.
      * For LLVersionInfo specifically, the 'const std::string&' return type was
        replaced with 'std::string'. Returning a reference to a static or a member,
        const or otherwise, is an anti-pattern: the interface constrains the
        implementation, prohibiting possibly later returning a temporary (an
        expression).
      * For LLVersionInfo specifically, 'const S32' return type was replaced with
        simple 'S32'. 'const' is just noise in that usage.
      * Simple member initialization (e.g. the original initializer expressions for
        static variables) can be done with member{ value } initializers (no examples
        here though).
      * Delete initClass() method.
      * LLSingleton's forté is of course lazy initialization. It might work to
        simply delete any calls to initClass(). But if there are side effects that
        must happen at that moment, replace LLSomeSingleton::initClass() with
        (void)LLSomeSingleton::instance();
      * Most initClass() initialization can be done in the constructor, as would
        normally be the case.
      * Initialization that might cause a circular LLSingleton reference should be
        moved to initSingleton(). Override 'void initSingleton();' should be private.
      * For LLVersionInfo specifically, certain initialization that used to be
        lazily performed was made unconditional, due to its low cost.
      * For LLVersionInfo specifically, certain initialization involved calling
        methods that have become non-static. This was moved to initSingleton()
        because, in a constructor body, 'this' does not yet point to the enclosing
        class.
      * Delete cleanupClass() method.
      * There is already a generic LLSingletonBase::deleteAll() call in
        LLAppViewer::cleanup(). It might work to let this new LLSingleton be cleaned
        up with all the rest. But if there are side effects that must happen at that
        moment, replace LLSomeSingleton::cleanupClass() with
        LLSomeSingleton::deleteSingleton(). That said, much of the benefit of
        converting to LLSingleton is deleteAll()'s guarantee that cross-LLSingleton
        dependencies will be properly honored: we're trying to migrate the code base
        away from the present fragile manual cleanup sequence.
      * Most cleanupClass() cleanup can be done in the destructor, as would normally
        be the case.
      * Cleanup that might throw an exception should be moved to cleanupSingleton().
        Override 'void cleanupSingleton();' should be private.
      * Within LLSomeSingleton methods, remove any existing
        LLSomeSingleton::methodName() qualification: simple methodName() is better.
      * In the rest of the code base, convert most LLSomeSingleton::methodName()
        references to LLSomeSingleton::instance().methodName(). (Prefer instance() to
        getInstance() because a reference does not admit the possibility of NULL.)
      * Of course, LLSomeSingleton::ENUM_VALUE can remain unchanged.
      
      In general, for many successive references to an LLSingleton instance, it
      can be useful to capture the instance() as in:
      
      auto& versionInfo{LLVersionInfo::instance()};
      // ... versionInfo.getVersion() ...
      
      We did not do that here only to simplify the code review.
      
      The STRINGIZE(expression) macro encapsulates:
      std::ostringstream out;
      out << expression;
      return out.str();
      We used that in a couple places.
      
      For LLVersionInfo specifically, lllogininstance_test.cpp used to dummy out a
      couple specific static methods. It's harder to dummy out
      LLSingleton::instance() references, so we add the real class to that test.
      5a260e0c
    • Nat Goodspeed's avatar
      SL-11216: Remove LLSingletonBase::cleanupAll(). · 47ec6ab3
      Nat Goodspeed authored
      Remove call from LLAppViewer::cleanup().
      
      Instead, make each LLSingleton<T>::deleteSingleton() call cleanupSingleton()
      just before destroying the instance. Since deleteSingleton() is not a
      destructor, it's fine to call cleanupSingleton() from there; and since
      deleteAll() calls deleteSingleton() on every remaining instance, the former
      cleanupAll() functionality has been subsumed into deleteAll().
      
      Since cleanupSingleton() is now called at exactly one point in the instance's
      lifetime, we no longer need a bool indicating whether it has been called.
      
      The previous protocol of calling cleanupAll() before deleteAll() implemented a
      two-phase cleanup strategy for the application. That is no longer needed.
      Moreover, the cleanupAll() / deleteAll() sequence created a time window during
      which individual LLSingleton<T> instances weren't usable (to the extent that
      their cleanupSingleton() methods released essential resources) but still
      existed -- so a getInstance() call would return the crippled instance rather
      than recreating it.
      
      Remove cleanupAll() calls from tests; adjust to new order of expected side
      effects: instead of A::cleanupSingleton(), B::cleanupSingleton(), ~A(), ~B(),
      now we get A::cleanupSingleton(), ~A(), B::cleanupSingleton(), ~B().
      47ec6ab3
    • Nat Goodspeed's avatar
    • Nat Goodspeed's avatar
      DRTVWR-494: Get initialized LLMutexes for very early log calls. · 4c9e90de
      Nat Goodspeed authored
      Use function-static LLMutex instances instead of module-static instances,
      since some log calls are evidently issued before we get around to initializing
      llerror.cpp module-static variables.
      4c9e90de
    • Nat Goodspeed's avatar
      DRTVWR-494: Move most LLSingleton cleanup back to destructor · 31863d83
      Nat Goodspeed authored
      instead of deleteSingleton().
      
      Specifically, clear static SingletonData and remove the instance from the
      MasterList in the destructor.
      
      Empirically, some consumers are manually deleting LLSingleton instances,
      instead of calling deleteSingleton(). If deleteSingleton() handles cleanup
      rather than the destructor, we're left with dangling pointers in the Master
      List.
      
      We don't also call cleanupSingleton() from the destructor because only
      deleteSingleton() promises to call cleanupSingleton(). Hopefully whoever is
      directly deleting an LLSingleton subclass instance isn't relying on
      cleanupSingleton().
      31863d83
    • Nat Goodspeed's avatar
      DRTVWR-494: Fix Windows macro collisions in windows_volume_catcher · b1477e98
      Nat Goodspeed authored
      by tweaking #include order.
      b1477e98
    • Nat Goodspeed's avatar
    • Nat Goodspeed's avatar
      DRTVWR-494: LLParamSingleton::initParamSingleton() on main thread. · 7e9c5dd0
      Nat Goodspeed authored
      When calling LLParamSingleton::initParamSingleton() on a secondary thread, use
      LLMainThreadTask::dispatch() to construct the instance on the main thread --
      as with LLSingleton::getInstance().
      7e9c5dd0
    • Nat Goodspeed's avatar
      DRTVWR-494: LLParamSingleton<T>::initParamSingleton() now returns T*. · 68505edf
      Nat Goodspeed authored
      So does LLLockedSingleton<T>::construct().
      68505edf
    • Nat Goodspeed's avatar
      DRTVWR-494: Dispatch all LLSingleton construction to the main thread. · a6f5e55d
      Nat Goodspeed authored
      Given the viewer's mutually-dependent LLSingletons, given that different
      threads might simultaneously request different LLSingletons from such a chain
      of circular dependencies, the key to avoiding deadlock is to serialize all
      LLSingleton construction on one thread: the main thread. Add comments to
      LLSingleton::getInstance() explaining the problem and the solution.
      
      Recast LLSingleton's static SingletonData to use LockStatic. Instead of using
      Locker, and simply trusting that every reference to sData is within the
      dynamic scope of a Locker instance, LockStatic enforces that: you can only
      access SingletonData members via LockStatic.
      
      Reorganize the switch in getInstance() to group the CONSTRUCTING error, the
      INITIALIZING/INITIALIZED success case, and the DELETED/UNINITIALIZED
      construction case.
      
      When [re]constructing an instance, on the main thread, retain the lock and
      call constructSingleton() (and capture_dependency()) directly.
      
      On a secondary thread, unlock LockStatic and use LLMainThreadTask::dispatch()
      to call getInstance() on the main thread. Since we might end up enqueuing
      multiple such tasks, it's important to let getInstance() notice when the
      instance has already been constructed and simply return the existing pointer.
      
      Add loginfos() method, sibling to logerrs(), logwarns() and logdebugs().
      Produce loginfos() messages when dispatching to the main thread, when actually
      running on the main thread and when resuming the suspended requesting thread.
      
      Make deleteSingleton() manage all associated state, instead of delegating some
      of that work to ~LLSingleton(). Now, within LockStatic, extract the instance
      pointer and set state to DELETED; that lets subsequent code, which retains the
      only remaining pointer to the instance, remove the master-list entry, call the
      subclass cleanupSingleton() and destructor without needing to hold the lock.
      
      In fact, entirely remove ~LLSingleton().
      
      Import LLSingletonBase::cleanup_() method to wrap the call to subclass
      cleanupSingleton() in try/catch.
      
      Remove cleanupAll() calls from llsingleton_test.cpp, and reorder the success
      cases to reflect the fact that T::cleanupSingleton() is called immediately
      before ~T() for each distinct LLSingleton subclass T.
      
      When getInstance() on a secondary thread dispatches to the main thread, it
      necessarily unlocks its LockStatic lock. But an LLSingleton dependency chain
      strongly depends on the function stack on which getInstance() is invoked --
      the task dispatched to the main thread doesn't know the dependencies tracked
      on the requesting thread stack. So, once the main thread delivers the instance
      pointer, the requesting thread captures its own dependencies for that
      instance.
      
      Back in the requesting thread, obtaining the current EInitState to pass to
      capture_dependencies() would have required relocking LockStatic. Instead, I've
      convinced myself that (a) capture_dependencies() only wanted to know
      EInitState to produce an error for CONSTRUCTING, and (b) in CONSTRUCTING
      state, we never get as far as capture_dependencies() because getInstance()
      produces an error first.
      
      Eliminate the EInitState parameter from all capture_dependencies() methods.
      Remove the LLSingletonBase::capture_dependency() stanza that tested
      EInitState. Make the capture_dependencies() variants that accepted LockStatic
      instead accept LLSingletonBase*. That lets getInstance(), in the
      LLMainThreadTask case, pass the newly-returned instance pointer.
      
      For symmetry, make pop_initializing() accept LLSingletonBase* as well, instead
      of accepting LockStatic and extracting mInstance.
      a6f5e55d
    • Nat Goodspeed's avatar
      DRTVWR-494: Fix VS LLError::Log::demangle() vulnerability. · 1fc7c994
      Nat Goodspeed authored
      The Windows implementation of demangle() assumed that a "mangled" class name
      produced by typeid(class).name() always starts with the prefix "class ",
      checked for that and removed it. If the mangled name didn't start with that
      prefix, it would emit a debug message and return the full name.
      
      When the class in question is actually a struct, the prefix is "struct "
      instead. But when demangle() was being called before logging had been fully
      initialized, the debug message remarking that it didn't start with "class "
      crashed.
      
      Look for either "class " or "struct " prefix. Remove whichever is found and
      return the rest of the name. If neither is found, only log if logging is
      available.
      1fc7c994
    • Nat Goodspeed's avatar
      DRTVWR-494: Remove LLMainThreadTask::dispatch(LockStatic&, ...) · 6586918d
      Nat Goodspeed authored
      Monty's code review reveals that conflating dispatch() with [un]lock
      functionality is inconsistent and unnecessary.
      6586918d
Loading