Skip to content

#1254 #472 Improved/fixed connection between app framework output provider and library streams

  • Easiest to understand per commit, but be aware of some things things getting changed again in later commits. See below for details.
  • Goal:
    • Ensure that threaded library code can use streams via the library steam interfaces without crashing, if the streams are backed by application framework streams, without threads having to be registered by the application framework.
    • Prevent unnecessary access to application streams via relatively-expensive ThreadLocal storage queries.
  • End-user visible changes:
    • Improved performance for stdout/stderr (console) output, for various applications.
  • Detailed changes:
    • OutputProvider: Introduced internal method for each 'do*'. Now, for every static method, there is a non-static internal one. And I ensured that internal methods only invoke internal methods, to that we can call them for the library implementation without requiring again the application framework.
    • OutputProvider: Some internal methods are OK to invoke directly, so, not necessarily via the corresponding static method. We do that for instance for the library stream implementations.
    • OutputProvider: Introduced output mode instance field. It gets initialized to the same default as the OutputModeOption, but is set later by the application to the configured output mode. This is not as nice as a final field (earlier commit), but its required to solve initialization order issues (later commit). Methods only access the field, not the option anymore.
    • OutputProvider: I got rid of static fields. In an earlier commit, these are removed completely. In a later commit, they are re-added as instance fields, for caching purposes, which I made thread-safe. The DebugNormalOutput, WarnOutput and ErrorOutput instances are created on demand, with caching added in a later commit.
    • Applications are adapted to the OutputProvider changes. First by invoking AppEnv.getProvider().get*(), and in a later commit by invoking getAppEnvData().getProvider().get*().
    • Libraries got adapted to not access the OutputProvider anymore or getting the streams. So, no more static calls there. Instead, they now get them forwarded from the applications.
    • ElimStateEvtExclInvs: Made providing the WarnOutput mandatory for the constructor. Prevents not passing it my mistake from libraries. Adapted all existing mistakes by forwarding it all the way from their applications.
    • Renamed Application.getProvider to createProvider. This avoids a lot of confusion. I previously invoked getProvider().get*() from application code, instead of AppEnv.getProvider().get*() (and later getAppEnvData().getProvider().get*()). This crashed. The rename avoids the confusion, as it makes it clear that createProvider doesn't return the already existing provider of the application, but creates a new one.
    • OutputModeOption: I've overridden postProcessValue and verifyValue, but kept the default implementation, documenting in comments that there must never in the future be custom code there, due to the specific initialization order of things.
    • CifToCifApp can now deal with CIF to CIF transformation classes that only have a contructor that requires a WarnOutput argument, rather than also having a default constructor.

Closes #1254 (closed) Addresses #472

Merge request reports

Loading