diff options
| author | Stefan Boberg <[email protected]> | 2025-03-12 14:48:46 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-03-12 14:48:46 +0100 |
| commit | cd128dd76526ed01c9a6c125b7ecddd9e3e08e57 (patch) | |
| tree | 62e1285564daefd49690a867bf76e54f23c8457b /src | |
| parent | fixes for log timestamps (#304) (diff) | |
| download | zen-cd128dd76526ed01c9a6c125b7ecddd9e3e08e57.tar.xz zen-cd128dd76526ed01c9a6c125b7ecddd9e3e08e57.zip | |
ProgressBar improvements (#305)
* changed ProgressBar so it doesn't use printf. printf by default is very slow on Windows due to weird buffering behaviour. During a 2 minute build download I profiled 35 CPU seconds inside printf
* changed so ProgressBar uses plain output mode if stdout is not a console/tty
Diffstat (limited to 'src')
| -rw-r--r-- | src/zen/zen.cpp | 43 | ||||
| -rw-r--r-- | src/zen/zen.h | 1 |
2 files changed, 42 insertions, 2 deletions
diff --git a/src/zen/zen.cpp b/src/zen/zen.cpp index 0fcf9d871..9d0eab7dc 100644 --- a/src/zen/zen.cpp +++ b/src/zen/zen.cpp @@ -32,6 +32,7 @@ #include <zencore/scopeguard.h> #include <zencore/string.h> #include <zencore/trace.h> +#include <zencore/windows.h> #include <zenhttp/httpcommon.h> #include <zenutil/logging.h> #include <zenutil/zenserverprocess.h> @@ -56,6 +57,10 @@ ZEN_THIRD_PARTY_INCLUDES_END #include <zencore/memory/newdelete.h> +#ifndef ZEN_PLATFORM_WINDOWS +# include <unistd.h> +#endif + ////////////////////////////////////////////////////////////////////////// namespace zen { @@ -261,8 +266,22 @@ ZenCmdBase::ResolveTargetHostSpec(const std::string& InHostSpec) return ResolveTargetHostSpec(InHostSpec, /* out */ Dummy); } +static bool +IsStdoutTty() +{ +#if ZEN_PLATFORM_WINDOWS + static HANDLE hStdOut = ::GetStdHandle(STD_OUTPUT_HANDLE); + DWORD dwMode = 0; + static bool IsConsole = ::GetConsoleMode(hStdOut, &dwMode); + return IsConsole; +#else + return isatty(fileno(stdout)); +#endif +} + ProgressBar::ProgressBar(bool PlainProgress, bool ShowDetails) -: m_PlainProgress(PlainProgress) +: m_StdoutIsTty(IsStdoutTty()) +, m_PlainProgress(PlainProgress || !m_StdoutIsTty) , m_ShowDetails(ShowDetails) , m_LastUpdateMS(m_SW.GetElapsedTimeMs() - 10000) { @@ -323,7 +342,27 @@ ProgressBar::UpdateState(const State& NewState, bool DoLinebreak) ETA, NewState.Details.empty() ? "" : fmt::format(". {}", NewState.Details)); std::string::size_type EraseLength = m_LastOutputLength > Output.length() ? (m_LastOutputLength - Output.length()) : 0; - printf("%s%s%s", Output.c_str(), std::string(EraseLength, ' ').c_str(), DoLinebreak ? "\n" : ""); + + ExtendableStringBuilder<128> LineToPrint; + LineToPrint << Output << std::string(EraseLength, ' '); + if (DoLinebreak) + LineToPrint << "\n"; + +#if ZEN_PLATFORM_WINDOWS + static HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + + if (m_StdoutIsTty) + { + WriteConsoleA(hStdOut, LineToPrint.c_str(), (DWORD)LineToPrint.Size(), 0, 0); + } + else + { + ::WriteFile(hStdOut, (LPCVOID)LineToPrint.c_str(), (DWORD)LineToPrint.Size(), 0, 0); + } +#else + fwrite(LineToPrint.c_str(), 1, LineToPrint.Size(), stdout); +#endif + m_LastOutputLength = DoLinebreak ? 0 : Output.length(); m_State = NewState; } diff --git a/src/zen/zen.h b/src/zen/zen.h index 835c2b6ac..6765101db 100644 --- a/src/zen/zen.h +++ b/src/zen/zen.h @@ -94,6 +94,7 @@ public: bool HasActiveTask() const; private: + const bool m_StdoutIsTty = true; const bool m_PlainProgress; const bool m_ShowDetails; Stopwatch m_SW; |