You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by an...@apache.org on 2018/06/28 18:22:27 UTC

[13/16] mesos git commit: Windows: Added `windows_to_unix_epoch` function.

Windows: Added `windows_to_unix_epoch` function.

There are a couple of places where we need to convert a Windows
absolute time (epoch at 01/01/1601) to a UNIX absolute time (epoch at
01/01/1970). So, a function has been added to handle it.

Review: https://reviews.apache.org/r/67685/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/184338e0
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/184338e0
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/184338e0

Branch: refs/heads/master
Commit: 184338e0992c3599a53e8e481a89a5b73e543e79
Parents: bfeda6b
Author: Akash Gupta <ak...@hotmail.com>
Authored: Wed Jun 27 14:30:15 2018 -0700
Committer: Andrew Schwartzmeyer <an...@schwartzmeyer.com>
Committed: Wed Jun 27 15:06:10 2018 -0700

----------------------------------------------------------------------
 .../stout/include/stout/os/windows/stat.hpp     | 25 +++-------------
 3rdparty/stout/include/stout/windows/os.hpp     | 30 ++++++++++++++++++++
 2 files changed, 34 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/184338e0/3rdparty/stout/include/stout/os/windows/stat.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/os/windows/stat.hpp b/3rdparty/stout/include/stout/os/windows/stat.hpp
index 7838bac..6225609 100644
--- a/3rdparty/stout/include/stout/os/windows/stat.hpp
+++ b/3rdparty/stout/include/stout/os/windows/stat.hpp
@@ -23,6 +23,8 @@
 
 #include <stout/os/int_fd.hpp>
 
+#include <stout/windows/os.hpp>
+
 #include <stout/internal/windows/attributes.hpp>
 #include <stout/internal/windows/longpath.hpp>
 #include <stout/internal/windows/reparsepoint.hpp>
@@ -166,27 +168,8 @@ inline Try<long> mtime(
     return WindowsError();
   }
 
-  // Convert to 64-bit integer using Windows magic.
-  ULARGE_INTEGER largetime;
-  largetime.LowPart = filetime.dwLowDateTime;
-  largetime.HighPart = filetime.dwHighDateTime;
-  // Now the `QuadPart` field is the 64-bit representation due to the
-  // layout of the `ULARGE_INTEGER` struct.
-  static_assert(
-      sizeof(largetime.QuadPart) == sizeof(__int64),
-      "Expected `QuadPart` to be of type `__int64`");
-  const __int64 windowstime = largetime.QuadPart;
-  // A file time is a 64-bit value that represents the number of
-  // 100-nanosecond intervals that have elapsed since 1601-01-01
-  // 00:00:00 +0000. However, users of this function expect UNIX time,
-  // which is seconds elapsed since the Epoch, 1970-01-01 00:00:00
-  // +0000.
-  //
-  // So first we convert 100-nanosecond intervals into seconds by
-  // doing `(x * 100) / (1,000^3)`, or `x / 10,000,000`, and then
-  // substracting the number of seconds between 1601-01-01 and
-  // 1970-01-01, or `11,644,473,600`.
-  const __int64 unixtime = (windowstime / 10000000) - 11644473600;
+  const uint64_t unixtime = os::internal::windows_to_unix_epoch(filetime);
+
   // We choose to make this conversion explicit because we expect the
   // truncation to not cause information loss.
   return static_cast<long>(unixtime);

http://git-wip-us.apache.org/repos/asf/mesos/blob/184338e0/3rdparty/stout/include/stout/windows/os.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/windows/os.hpp b/3rdparty/stout/include/stout/windows/os.hpp
index 46cd667..4f26806 100644
--- a/3rdparty/stout/include/stout/windows/os.hpp
+++ b/3rdparty/stout/include/stout/windows/os.hpp
@@ -80,6 +80,36 @@ inline Try<std::string> nodename()
   return stringify(std::wstring(buffer.data()));
 }
 
+
+// Converts a `FILETIME` from an absoute Windows time, which is the number of
+// 100-nanosecond intervals since 1601-01-01 00:00:00 +0000, to an UNIX
+// absolute time, which is number of seconds from 1970-01-01 00:00:00 +0000.
+inline double windows_to_unix_epoch(const FILETIME& filetime)
+{
+  ULARGE_INTEGER time;
+
+  // `FILETIME` isn't 8 byte aligned so they suggest not do cast to int64*.
+  time.HighPart = filetime.dwHighDateTime;
+  time.LowPart = filetime.dwLowDateTime;
+
+  // Constant taken from here:
+  // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724228(v=vs.85).aspx. // NOLINT(whitespace/line_length)
+  // It is the number of 100ns periods between the Windows and UNIX epochs.
+  constexpr uint64_t epoch_offset = 116444736000000000ULL;
+
+  // Now the `QuadPart` field is the 64-bit representation due to the
+  // layout of the `ULARGE_INTEGER` struct.
+  static_assert(
+      std::is_same<decltype(time.QuadPart), uint64_t>::value,
+      "Expected `ULARGE_INTEGER.QuadPart` to be of type `uint64_t`");
+
+  CHECK_GE(time.QuadPart, epoch_offset)
+    << "windows_to_unix_epoch: Given time was before UNIX epoch: "
+    << time.QuadPart;
+
+  return static_cast<double>(time.QuadPart - epoch_offset) / 10000000;
+}
+
 } // namespace internal {