From 4ad1a241281d3e8fd0b28388c0191c044ac3d788 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 21 Nov 2018 12:40:09 +0200 Subject: More backwards modification time experimentation --- build2/cc/link-rule.cxx | 3 ++- build2/depdb.cxx | 47 ++++++++++++++++++++++++++++++++++------------- build2/depdb.hxx | 2 +- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/build2/cc/link-rule.cxx b/build2/cc/link-rule.cxx index 981358e..2581d6f 100644 --- a/build2/cc/link-rule.cxx +++ b/build2/cc/link-rule.cxx @@ -2076,7 +2076,7 @@ namespace build2 timestamp dd_tt (system_clock::now ()); #endif - dd.close (); + timestamp dd_cl (dd.close ()); // If nothing changed, then we are done. // @@ -2569,6 +2569,7 @@ namespace build2 if (dd_mt > tp_mt) fail << "backwards modification times:\n" << dd_tt << " window start\n" + << dd_cl << " write mtime\n" << dd.mtime << " close mtime\n" << dd_mt << " " << dd.path.string () << '\n' << tp_mt << " " << tp.string () << '\n' diff --git a/build2/depdb.cxx b/build2/depdb.cxx index f0b0d21..088b355 100644 --- a/build2/depdb.cxx +++ b/build2/depdb.cxx @@ -6,6 +6,10 @@ #include // file_mtime() +#ifdef _WIN32 +# include +#endif + #include using namespace std; @@ -201,7 +205,7 @@ namespace build2 fs_.put ('\n'); } - void depdb:: + timestamp depdb:: close () { // If we are at eof, then it means all lines are good, there is the "end @@ -259,34 +263,51 @@ namespace build2 // getting the old mtime if we ask for it too soon. For such cases we are // going to just set it ourselves. // -#if defined(_WIN32) || defined(__FreeBSD__) -# define BUILD2_NEED_MTIME_FIX -#endif - -#ifdef BUILD2_NEED_MTIME_FIX - timestamp mt; +#ifdef _WIN32 + timestamp mt (timestamp_unknown); #endif if (state_ == state::write) { -#ifdef BUILD2_NEED_MTIME_FIX - mt = system_clock::now (); +#ifdef _WIN32 + FILETIME ft; + GetSystemTimeAsFileTime (&ft); + + // See libbutl/filesystem.cxx for details. + // + uint64_t nsec ((static_cast (ft.dwHighDateTime) << 32) | + ft.dwLowDateTime); + nsec -= 11644473600ULL * 10000000; + nsec *= 100; + + mt = timestamp ( + chrono::duration_cast (chrono::nanoseconds (nsec))); #endif + fs_.put ('\0'); // The "end marker". } fs_.close (); -#ifdef BUILD2_NEED_MTIME_FIX +#if defined(_WIN32) || defined(__FreeBSD__) if (state_ == state::write) { - // Save the original returned time for debugging. - // - mtime = file_mtime (path); + mtime = file_mtime (path); // Save for debugging. +#ifdef _WIN32 if (mtime < mt) + { file_mtime (path, mt); + assert (file_mtime (path) == mt); + } +#endif } #endif + +#ifdef _WIN32 + return mt; +#else + return timestamp_unknown; +#endif } } diff --git a/build2/depdb.hxx b/build2/depdb.hxx index 7c9e464..ffb3b89 100644 --- a/build2/depdb.hxx +++ b/build2/depdb.hxx @@ -90,7 +90,7 @@ namespace build2 // may be left in the old/currupt state. Note that in the read mode this // function will "chop off" lines that haven't been read. // - void + timestamp close (); // Read the next line. If the result is not NULL, then it is a pointer to -- cgit v1.1