From ed76289b259d42d0a57c147e791e2c235ed28805 Mon Sep 17 00:00:00 2001
From: costan <costan@google.com>
Date: Thu, 7 Mar 2019 08:52:24 -0800
Subject: [PATCH] Align windows_logger with posix_logger.

Fixes GitHub issue #657.

This CL also makes the Windows CI green.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=237255887
---
 CMakeLists.txt        | 20 ++++++++++----------
 util/env_windows.cc   | 14 +++++++-------
 util/windows_logger.h | 35 ++++++++++++++++++++++-------------
 3 files changed, 39 insertions(+), 30 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1eaf48e..1562e3e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -188,17 +188,17 @@ target_sources(leveldb
 )
 
 if (WIN32)
-target_sources(leveldb
-  PRIVATE
-    "${PROJECT_SOURCE_DIR}/util/env_windows.cc"
-    "${PROJECT_SOURCE_DIR}/util/windows_logger.h"
-)
+  target_sources(leveldb
+    PRIVATE
+      "${PROJECT_SOURCE_DIR}/util/env_windows.cc"
+      "${PROJECT_SOURCE_DIR}/util/windows_logger.h"
+  )
 else (WIN32)
-target_sources(leveldb
-  PRIVATE
-    "${PROJECT_SOURCE_DIR}/util/env_posix.cc"
-    "${PROJECT_SOURCE_DIR}/util/posix_logger.h"
-)
+  target_sources(leveldb
+    PRIVATE
+      "${PROJECT_SOURCE_DIR}/util/env_posix.cc"
+      "${PROJECT_SOURCE_DIR}/util/posix_logger.h"
+  )
 endif (WIN32)
 
 # MemEnv is not part of the interface and could be pulled to a separate library.
diff --git a/util/env_windows.cc b/util/env_windows.cc
index 03da266..57932bb 100644
--- a/util/env_windows.cc
+++ b/util/env_windows.cc
@@ -621,15 +621,15 @@ class WindowsEnv : public Env {
     return Status::OK();
   }
 
-  Status NewLogger(const std::string& fname, Logger** result) override {
-    ScopedHandle handle =
-        ::CreateFileA(fname.c_str(), GENERIC_WRITE, FILE_SHARE_READ, nullptr,
-                      CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
-    if (!handle.is_valid()) {
+  Status NewLogger(const std::string& filename, Logger** result) override {
+    std::FILE* fp = std::fopen(filename.c_str(), "w");
+    if (fp == nullptr) {
+      *result = nullptr;
       return WindowsError("NewLogger", ::GetLastError());
+    } else {
+      *result = new WindowsLogger(fp);
+      return Status::OK();
     }
-    *result = new WindowsLogger(handle.Release());
-    return Status::OK();
   }
 
   uint64_t NowMicros() override {
diff --git a/util/windows_logger.h b/util/windows_logger.h
index b2a2cae..96799bc 100644
--- a/util/windows_logger.h
+++ b/util/windows_logger.h
@@ -7,10 +7,9 @@
 #ifndef STORAGE_LEVELDB_UTIL_WINDOWS_LOGGER_H_
 #define STORAGE_LEVELDB_UTIL_WINDOWS_LOGGER_H_
 
-#include <stdio.h>
-
 #include <cassert>
 #include <cstdarg>
+#include <cstdio>
 #include <ctime>
 #include <sstream>
 #include <thread>
@@ -21,11 +20,16 @@ namespace leveldb {
 
 class WindowsLogger final : public Logger {
  public:
-  WindowsLogger(HANDLE handle) : handle_(handle) {
-    assert(handle != INVALID_HANDLE_VALUE);
+  // Creates a logger that writes to the given file.
+  //
+  // The PosixLogger instance takes ownership of the file handle.
+  explicit WindowsLogger(std::FILE* fp) : fp_(fp) {
+    assert(fp != nullptr);
   }
 
-  ~WindowsLogger() override { ::CloseHandle(handle_); }
+  ~WindowsLogger() override {
+    std::fclose(fp_);
+  }
 
   void Logv(const char* format, va_list arguments) override {
     // Record the time as close to the Logv() call as possible.
@@ -56,16 +60,20 @@ class WindowsLogger final : public Logger {
           (iteration == 0) ? stack_buffer : new char[dynamic_buffer_size];
 
       // Print the header into the buffer.
-      // TODO(costan): Sync this logger with another logger.
       int buffer_offset = snprintf(
-          buffer, buffer_size, "%04d/%02d/%02d-%02d:%02d:%02d.%06d %s ",
-          now_components.wYear, now_components.wMonth, now_components.wDay,
-          now_components.wHour, now_components.wMinute, now_components.wSecond,
+          buffer, buffer_size,
+          "%04d/%02d/%02d-%02d:%02d:%02d.%06d %s ",
+          now_components.wYear,
+          now_components.wMonth,
+          now_components.wDay,
+          now_components.wHour,
+          now_components.wMinute,
+          now_components.wSecond,
           static_cast<int>(now_components.wMilliseconds * 1000),
-          std::stoull(thread_id));
+          thread_id.c_str());
 
       // The header can be at most 28 characters (10 date + 15 time +
-      // 3 spacing) plus the thread ID, which should fit comfortably into the
+      // 3 delimiters) plus the thread ID, which should fit comfortably into the
       // static buffer.
       assert(buffer_offset <= 28 + kMaxThreadIdSize);
       static_assert(28 + kMaxThreadIdSize < kStackBufferSize,
@@ -106,7 +114,8 @@ class WindowsLogger final : public Logger {
       }
 
       assert(buffer_offset <= buffer_size);
-      ::WriteFile(handle_, buffer, buffer_offset, nullptr, nullptr);
+      std::fwrite(buffer, 1, buffer_offset, fp_);
+      std::fflush(fp_);
 
       if (iteration != 0) {
         delete[] buffer;
@@ -116,7 +125,7 @@ class WindowsLogger final : public Logger {
   }
 
  private:
-  HANDLE handle_;
+  std::FILE* const fp_;
 };
 
 }  // namespace leveldb