From 6b67fe61528356f7ebe9aa6e6060b1cd91a71d2f Mon Sep 17 00:00:00 2001 From: Juha Sointusalo Date: Mon, 17 Jul 2017 21:58:23 +0300 Subject: [PATCH] client/lib: don't flush stdout and stderr in main loop The client flushes stdout and stderr at every iteration of the main loop. On Windows, stderr is opened in commit mode and this results in a write to NTFS $Log every time the stream is flushed even if nothing was written to the stream since last flush. These unnecessary writes totals to several hundred megabytes per day. Some users are concerned that this shortens the lifespan of their hardware. Fix this by removing the flushes from main loop. stderr is unbuffered so it never needed the flush. After freopen() in diagnostics_init() stdout is fully buffered. Change stdout to line buffered mode so that log messages are visible in log files immediately. MSVCRT doesn't support line buffered streams. It treats them as fully buffered. Emulate line buffered stream by flushing stdout in logging functions when compiling with Visual C++. --- client/client_msgs.cpp | 5 +++++ client/main.cpp | 6 ++++-- lib/diagnostics.cpp | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/client/client_msgs.cpp b/client/client_msgs.cpp index 356fdddcdb..8c158a90d0 100644 --- a/client/client_msgs.cpp +++ b/client/client_msgs.cpp @@ -125,6 +125,11 @@ void show_message( // print message to the console printf("%s", evt_message); +#ifdef _MSC_VER + // MSVCRT doesn't support line buffered streams + fflush(stdout); +#endif + // print message to the debugger view port diagnostics_trace_to_debugger(evt_message); } diff --git a/client/main.cpp b/client/main.cpp index e4fd1e87e2..0c76d6e8fc 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -83,6 +83,10 @@ void log_message_startup(const char* msg) { ); if (!gstate.executing_as_daemon) { fprintf(stdout, "%s", evt_msg); +#ifdef _MSC_VER + // MSVCRT doesn't support line buffered streams + fflush(stdout); +#endif } else { #ifdef _WIN32 LogEventInfoMessage(evt_msg); @@ -373,8 +377,6 @@ int boinc_main_loop() { if (!gstate.poll_slow_events()) { gstate.do_io_or_sleep(POLL_INTERVAL); } - fflush(stderr); - fflush(stdout); if (gstate.time_to_exit()) { msg_printf(NULL, MSG_INFO, "Time to exit"); diff --git a/lib/diagnostics.cpp b/lib/diagnostics.cpp index bdd1707497..ec3704abce 100644 --- a/lib/diagnostics.cpp +++ b/lib/diagnostics.cpp @@ -352,6 +352,7 @@ int diagnostics_init( if (!stdout_file) { return ERR_FOPEN; } + setvbuf(stdout_file, NULL, _IOLBF, BUFSIZ); } if (flags & BOINC_DIAG_REDIRECTSTDOUTOVERWRITE) { @@ -359,6 +360,7 @@ int diagnostics_init( if (!stdout_file) { return ERR_FOPEN; } + setvbuf(stdout_file, NULL, _IOLBF, BUFSIZ); }