diff options
author | Maksim Denisov <denisov.maksim@huawei.com> | 2024-11-29 10:04:10 +0100 |
---|---|---|
committer | Maksim Denisov <denisov.maksim@huawei.com> | 2024-12-02 11:04:20 +0100 |
commit | af759f79b9a04ea914edf35037951c1fe993d824 (patch) | |
tree | a0fc7ce5ac70f2eb989e0bc65d7748c367b28c53 /src/other_tools/ops_maps | |
parent | d07e94d98d213cf16ff597d7da5ab6ca892e9f10 (diff) | |
download | justbuild-af759f79b9a04ea914edf35037951c1fe993d824.tar.gz |
Store keys in CriticalGitOpGuard's map
Diffstat (limited to 'src/other_tools/ops_maps')
-rw-r--r-- | src/other_tools/ops_maps/critical_git_op_map.hpp | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/src/other_tools/ops_maps/critical_git_op_map.hpp b/src/other_tools/ops_maps/critical_git_op_map.hpp index badf5235..3e5a07ee 100644 --- a/src/other_tools/ops_maps/critical_git_op_map.hpp +++ b/src/other_tools/ops_maps/critical_git_op_map.hpp @@ -23,6 +23,7 @@ #include <optional> #include <string> #include <unordered_map> +#include <utility> #include "src/buildtool/multithreading/async_map_consumer.hpp" #include "src/other_tools/git_operations/git_ops_types.hpp" @@ -71,21 +72,24 @@ class CriticalGitOpGuard { -> std::optional<GitOpKey> { // making sure only one thread at a time processes this section std::scoped_lock<std::mutex> const lock(critical_key_mutex_); - auto target_path_key = - std::hash<std::filesystem::path>{}(new_key.params.target_path); - if (curr_critical_key_.contains(target_path_key)) { - GitOpKey old_key = - curr_critical_key_[target_path_key]; // return stored key - curr_critical_key_[target_path_key] = - new_key; // replace stored key with new one - return old_key; + // try emplace a new value + + auto const canonical_path = std::filesystem::weakly_canonical( + std::filesystem::absolute(new_key.params.target_path)); + auto result = curr_critical_key_.try_emplace(canonical_path, new_key); + // If the insertion happens, there are no keys to wait for. std::nullopt + // is returned. + if (result.second) { + return std::nullopt; } - return std::nullopt; - // mutex released when lock goes out of scope + // If insertion fails (the path is being processed), mark the path + // occupied by the new key, but return the previous key to inform + // the new task to wait for the previous operation to complete. + return std::exchange(result.first->second, new_key); } private: - std::unordered_map<size_t, GitOpKey> curr_critical_key_; + std::unordered_map<std::filesystem::path, GitOpKey> curr_critical_key_; std::mutex critical_key_mutex_; }; |