aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src
diff options
context:
space:
mode:
authorNicole Mazzuca <t-nimaz@microsoft.com>2019-07-08 16:45:27 -0700
committerNicole Mazzuca <t-nimaz@microsoft.com>2019-07-11 18:20:35 -0700
commit5857e2c680fde9e37abc8f799f8d5509dd47ed62 (patch)
treef8d808ad5e51592d960869be5360db2375d29bad /toolsrc/src
parent7dbe375a2c270e91f9742dd78cf2b579d1f5f2fa (diff)
downloadvcpkg-5857e2c680fde9e37abc8f799f8d5509dd47ed62.tar.gz
vcpkg-5857e2c680fde9e37abc8f799f8d5509dd47ed62.zip
initial remove-in-parallel
doesn't actually do parallel remove yet
Diffstat (limited to 'toolsrc/src')
-rw-r--r--toolsrc/src/vcpkg/base/files.cpp68
-rw-r--r--toolsrc/src/vcpkg/base/rng.cpp14
2 files changed, 66 insertions, 16 deletions
diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp
index 5099795e9..d0926bb4c 100644
--- a/toolsrc/src/vcpkg/base/files.cpp
+++ b/toolsrc/src/vcpkg/base/files.cpp
@@ -1,6 +1,7 @@
#include "pch.h"
#include <vcpkg/base/files.h>
+#include <vcpkg/base/rng.h>
#include <vcpkg/base/system.debug.h>
#include <vcpkg/base/system.h>
#include <vcpkg/base/system.print.h>
@@ -256,26 +257,61 @@ namespace vcpkg::Files
virtual bool remove(const fs::path& path, std::error_code& ec) override { return fs::stdfs::remove(path, ec); }
virtual std::uintmax_t remove_all(const fs::path& path, std::error_code& ec) override
{
- // Working around the currently buggy remove_all()
- std::uintmax_t out = fs::stdfs::remove_all(path, ec);
+ /*
+ does not use the std::filesystem call since it is buggy, and can
+ have spurious errors before VS 2017 update 6, and on later versions
+ (as well as on macOS and Linux), this is just as fast and will have
+ fewer spurious errors due to locks.
+ */
+ struct recursive {
+ const fs::path& tmp_directory;
+ std::error_code& ec;
+ xoshiro256ss_engine& rng;
+
+ void operator()(const fs::path& current) const {
+ const auto type = fs::stdfs::symlink_status(current, ec).type();
+ if (ec) return;
+
+ const auto tmp_name = Strings::b64url_encode(rng());
+ const auto tmp_path = tmp_directory / tmp_name;
+
+ switch (type) {
+ case fs::file_type::directory: {
+ fs::stdfs::rename(current, tmp_path, ec);
+ if (ec) return;
+ for (const auto& entry : fs::stdfs::directory_iterator(tmp_path)) {
+ (*this)(entry);
+ }
+ fs::stdfs::remove(tmp_path, ec);
+ } break;
+ case fs::file_type::symlink:
+ case fs::file_type::regular: {
+ fs::stdfs::rename(current, tmp_path, ec);
+ fs::stdfs::remove(current, ec);
+ } break;
+ case fs::file_type::not_found: return;
+ case fs::file_type::none: {
+ Checks::exit_with_message(VCPKG_LINE_INFO, "Error occurred when evaluating file type of file: %s", current);
+ }
+ default: {
+ Checks::exit_with_message(VCPKG_LINE_INFO, "Attempted to delete special file: %s", current);
+ }
+ }
+ }
+ };
- for (int i = 0; i < 5 && this->exists(path); i++)
- {
- using namespace std::chrono_literals;
- std::this_thread::sleep_for(i * 100ms);
- out += fs::stdfs::remove_all(path, ec);
- }
+ auto const real_path = fs::stdfs::absolute(path);
- if (this->exists(path))
- {
- System::print2(
- System::Color::warning,
- "Some files in ",
- path.u8string(),
- " were unable to be removed. Close any editors operating in this directory and retry.\n");
+ if (! real_path.has_parent_path()) {
+ Checks::exit_with_message(VCPKG_LINE_INFO, "Attempted to remove_all the base directory");
}
- return out;
+ // thoughts: is this fine? or should we do something different?
+ // maybe a temporary directory?
+ auto const base_path = real_path.parent_path();
+
+ xoshiro256ss_engine rng{};
+ recursive{base_path, ec, rng}(real_path);
}
virtual bool exists(const fs::path& path) const override { return fs::stdfs::exists(path); }
virtual bool is_directory(const fs::path& path) const override { return fs::stdfs::is_directory(path); }
diff --git a/toolsrc/src/vcpkg/base/rng.cpp b/toolsrc/src/vcpkg/base/rng.cpp
new file mode 100644
index 000000000..9fe2ea3b4
--- /dev/null
+++ b/toolsrc/src/vcpkg/base/rng.cpp
@@ -0,0 +1,14 @@
+#include <base/rng.h>
+
+namespace vcpkg {
+ namespace {
+ std::random_device system_entropy{};
+ }
+
+ splitmix64_engine::splitmix64_engine() {
+ std::uint64_t top_half = system_entropy();
+ std::uint64_t bottom_half = system_entropy();
+
+ state = (top_half << 32) | bottom_half;
+ }
+}