aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/include
diff options
context:
space:
mode:
authorRobert Schumacher <roschuma@microsoft.com>2017-08-25 16:03:57 -0700
committerRobert Schumacher <roschuma@microsoft.com>2017-08-25 16:03:57 -0700
commit98ee8a949ad4bfdfa9bf0411b552a23c923eaff7 (patch)
tree84ffd2ba562550286e5327ccb8946076942f0934 /toolsrc/include
parent34bd87c9fcfb1ac9269c75db96852b64ed754d11 (diff)
downloadvcpkg-98ee8a949ad4bfdfa9bf0411b552a23c923eaff7.tar.gz
vcpkg-98ee8a949ad4bfdfa9bf0411b552a23c923eaff7.zip
[vcpkg] Trap Ctrl-C, enable thread safety for global data structures
Diffstat (limited to 'toolsrc/include')
-rw-r--r--toolsrc/include/metrics.h30
-rw-r--r--toolsrc/include/pch.h2
-rw-r--r--toolsrc/include/vcpkg_GlobalState.h11
-rw-r--r--toolsrc/include/vcpkg_Util.h31
4 files changed, 59 insertions, 15 deletions
diff --git a/toolsrc/include/metrics.h b/toolsrc/include/metrics.h
index 1f5ae2f32..8eae426de 100644
--- a/toolsrc/include/metrics.h
+++ b/toolsrc/include/metrics.h
@@ -2,19 +2,27 @@
#include <string>
+#include "vcpkg_Util.h"
+
namespace vcpkg::Metrics
{
- void set_send_metrics(bool should_send_metrics);
- void set_print_metrics(bool should_print_metrics);
- void set_user_information(const std::string& user_id, const std::string& first_use_time);
- void init_user_information(std::string& user_id, std::string& first_use_time);
+ struct Metrics : Util::ResourceBase
+ {
+ void set_send_metrics(bool should_send_metrics);
+ void set_print_metrics(bool should_print_metrics);
+ void set_user_information(const std::string& user_id, const std::string& first_use_time);
+ void init_user_information(std::string& user_id, std::string& first_use_time);
- void track_metric(const std::string& name, double value);
- void track_property(const std::string& name, const std::string& value);
- void track_property(const std::string& name, const std::wstring& value);
- bool get_compiled_metrics_enabled();
- std::wstring get_SQM_user();
+ void track_metric(const std::string& name, double value);
+ void track_property(const std::string& name, const std::string& value);
+ void track_property(const std::string& name, const std::wstring& value);
+
+ void upload(const std::string& payload);
+ void flush();
+ };
- void upload(const std::string& payload);
- void flush();
+ extern Util::LockGuarded<Metrics> g_metrics;
+
+ std::wstring get_SQM_user();
+ bool get_compiled_metrics_enabled();
}
diff --git a/toolsrc/include/pch.h b/toolsrc/include/pch.h
index 406d0741e..770bcf07a 100644
--- a/toolsrc/include/pch.h
+++ b/toolsrc/include/pch.h
@@ -7,6 +7,7 @@
#include <algorithm>
#include <array>
+#include <atomic>
#include <cassert>
#include <cctype>
#include <chrono>
@@ -22,6 +23,7 @@
#include <iterator>
#include <map>
#include <memory>
+#include <mutex>
#include <process.h>
#include <regex>
#include <set>
diff --git a/toolsrc/include/vcpkg_GlobalState.h b/toolsrc/include/vcpkg_GlobalState.h
index 15b8867f7..8f47fa00f 100644
--- a/toolsrc/include/vcpkg_GlobalState.h
+++ b/toolsrc/include/vcpkg_GlobalState.h
@@ -1,13 +1,16 @@
#pragma once
-#include <vcpkg_Chrono.h>
+#include <atomic>
+
+#include "vcpkg_Chrono.h"
+#include "vcpkg_Util.h"
namespace vcpkg
{
struct GlobalState
{
- static ElapsedTime timer;
- static bool debugging;
- static bool feature_packages;
+ static Util::LockGuarded<ElapsedTime> timer;
+ static std::atomic<bool> debugging;
+ static std::atomic<bool> feature_packages;
};
} \ No newline at end of file
diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h
index cfbd23020..c76ca01ac 100644
--- a/toolsrc/include/vcpkg_Util.h
+++ b/toolsrc/include/vcpkg_Util.h
@@ -1,6 +1,7 @@
#pragma once
#include <map>
+#include <mutex>
#include <utility>
#include <vector>
@@ -95,4 +96,34 @@ namespace vcpkg::Util
ResourceBase& operator=(const ResourceBase&) = delete;
ResourceBase& operator=(ResourceBase&&) = delete;
};
+
+ template<class T>
+ struct LockGuardPtr;
+
+ template<class T>
+ struct LockGuarded
+ {
+ friend struct LockGuardPtr<T>;
+
+ LockGuardPtr<T> lock() { return *this; }
+
+ private:
+ std::mutex m_mutex;
+ T m_t;
+ };
+
+ template<class T>
+ struct LockGuardPtr
+ {
+ T& operator*() { return m_ptr; }
+ T* operator->() { return &m_ptr; }
+
+ T* get() { return &m_ptr; }
+
+ LockGuardPtr(LockGuarded<T>& sync) : m_lock(sync.m_mutex), m_ptr(sync.m_t) {}
+
+ private:
+ std::unique_lock<std::mutex> m_lock;
+ T& m_ptr;
+ };
} \ No newline at end of file