aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2025-03-12 14:48:46 +0100
committerGitHub Enterprise <[email protected]>2025-03-12 14:48:46 +0100
commitcd128dd76526ed01c9a6c125b7ecddd9e3e08e57 (patch)
tree62e1285564daefd49690a867bf76e54f23c8457b /src
parentfixes for log timestamps (#304) (diff)
downloadzen-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.cpp43
-rw-r--r--src/zen/zen.h1
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;