diff options
| author | Stefan Boberg <[email protected]> | 2023-12-11 13:09:03 +0100 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2023-12-11 13:09:03 +0100 |
| commit | 93afeddbc7a5b5df390a29407f5515acd5a70fc1 (patch) | |
| tree | 6f85ee551aabe20dece64a750c0b2d5d2c5d2d5d /src/zencore/include | |
| parent | removed unnecessary SHA1 references (diff) | |
| parent | Make sure that PathFromHandle don't hide true error when throwing exceptions ... (diff) | |
| download | zen-93afeddbc7a5b5df390a29407f5515acd5a70fc1.tar.xz zen-93afeddbc7a5b5df390a29407f5515acd5a70fc1.zip | |
Merge branch 'main' of https://github.com/EpicGames/zen
Diffstat (limited to 'src/zencore/include')
| -rw-r--r-- | src/zencore/include/zencore/assertfmt.h | 48 | ||||
| -rw-r--r-- | src/zencore/include/zencore/blockingqueue.h | 40 | ||||
| -rw-r--r-- | src/zencore/include/zencore/compactbinarybuilder.h | 18 | ||||
| -rw-r--r-- | src/zencore/include/zencore/filesystem.h | 9 | ||||
| -rw-r--r-- | src/zencore/include/zencore/iobuffer.h | 3 | ||||
| -rw-r--r-- | src/zencore/include/zencore/logbase.h | 3 | ||||
| -rw-r--r-- | src/zencore/include/zencore/logging.h | 12 | ||||
| -rw-r--r-- | src/zencore/include/zencore/process.h | 98 | ||||
| -rw-r--r-- | src/zencore/include/zencore/string.h | 13 | ||||
| -rw-r--r-- | src/zencore/include/zencore/thread.h | 84 | ||||
| -rw-r--r-- | src/zencore/include/zencore/trace.h | 5 | ||||
| -rw-r--r-- | src/zencore/include/zencore/windows.h | 1 |
12 files changed, 230 insertions, 104 deletions
diff --git a/src/zencore/include/zencore/assertfmt.h b/src/zencore/include/zencore/assertfmt.h new file mode 100644 index 000000000..56383ffd9 --- /dev/null +++ b/src/zencore/include/zencore/assertfmt.h @@ -0,0 +1,48 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include <zencore/zencore.h> + +#include <fmt/args.h> +#include <string_view> + +namespace zen { + +namespace assert { + template<typename... T> + auto AssertCaptureArguments(T&&... Args) + { + return fmt::make_format_args(Args...); + } + + void ExecAssertFmt + [[noreturn]] (const char* Filename, int LineNumber, const char* FunctionName, std::string_view Format, fmt::format_args Args); + + // MSVC (v19.00.24215.1 at time of writing) ignores no-inline attributes on + // lambdas. This can be worked around by calling the lambda from inside this + // templated (and correctly non-inlined) function. + template<typename RetType = void, class InnerType, typename... ArgTypes> + RetType ZEN_FORCENOINLINE ZEN_DEBUG_SECTION CallColdNoInline(InnerType&& Inner, ArgTypes const&... Args) + { + return Inner(Args...); + } + +} // namespace assert + +#define ZEN_ASSERT_FORMAT(x, fmt, ...) \ + do \ + { \ + using namespace std::literals; \ + if (x) [[likely]] \ + break; \ + zen::assert::CallColdNoInline([&]() ZEN_FORCEINLINE { \ + zen::assert::ExecAssertFmt(__FILE__, \ + __LINE__, \ + __FUNCTION__, \ + "assert(" #x ") failed: " fmt ""sv, \ + zen::assert::AssertCaptureArguments(__VA_ARGS__)); \ + }); \ + } while (false) + +} // namespace zen diff --git a/src/zencore/include/zencore/blockingqueue.h b/src/zencore/include/zencore/blockingqueue.h index f92df5a54..e91fdc659 100644 --- a/src/zencore/include/zencore/blockingqueue.h +++ b/src/zencore/include/zencore/blockingqueue.h @@ -22,7 +22,6 @@ public: { std::lock_guard Lock(m_Lock); m_Queue.emplace_back(std::move(Item)); - m_Size++; } m_NewItemSignal.notify_one(); @@ -30,31 +29,33 @@ public: bool WaitAndDequeue(T& Item) { - if (m_CompleteAdding.load()) - { - return false; - } - std::unique_lock Lock(m_Lock); - m_NewItemSignal.wait(Lock, [this]() { return !m_Queue.empty() || m_CompleteAdding.load(); }); - - if (!m_Queue.empty()) + if (m_Queue.empty()) { - Item = std::move(m_Queue.front()); - m_Queue.pop_front(); - m_Size--; - - return true; + if (m_CompleteAdding) + { + return false; + } + m_NewItemSignal.wait(Lock, [this]() { return !m_Queue.empty() || m_CompleteAdding; }); + if (m_Queue.empty()) + { + ZEN_ASSERT(m_CompleteAdding); + return false; + } } - - return false; + Item = std::move(m_Queue.front()); + m_Queue.pop_front(); + return true; } void CompleteAdding() { - if (!m_CompleteAdding.load()) + std::unique_lock Lock(m_Lock); + if (!m_CompleteAdding) { - m_CompleteAdding.store(true); + m_CompleteAdding = true; + + Lock.unlock(); m_NewItemSignal.notify_all(); } } @@ -69,8 +70,7 @@ private: mutable std::mutex m_Lock; std::condition_variable m_NewItemSignal; std::deque<T> m_Queue; - std::atomic_bool m_CompleteAdding{false}; - std::atomic_uint32_t m_Size; + bool m_CompleteAdding = false; }; } // namespace zen diff --git a/src/zencore/include/zencore/compactbinarybuilder.h b/src/zencore/include/zencore/compactbinarybuilder.h index 89f69c1ab..9c81cf490 100644 --- a/src/zencore/include/zencore/compactbinarybuilder.h +++ b/src/zencore/include/zencore/compactbinarybuilder.h @@ -654,6 +654,24 @@ operator<<(CbWriter& Writer, const Oid& Value) ZENCORE_API CbWriter& operator<<(CbWriter& Writer, DateTime Value); ZENCORE_API CbWriter& operator<<(CbWriter& Writer, TimeSpan Value); +ZENCORE_API inline TimeSpan +ToTimeSpan(std::chrono::seconds Secs) +{ + return TimeSpan(0, 0, gsl::narrow<int>(Secs.count())); +}; +ZENCORE_API inline TimeSpan +ToTimeSpan(std::chrono::milliseconds MS) +{ + return TimeSpan(MS.count() * TimeSpan::TicksPerMillisecond); +} +ZENCORE_API inline DateTime +ToDateTime(std::chrono::system_clock::time_point TimePoint) +{ + time_t Time = std::chrono::system_clock::to_time_t(TimePoint); + tm UTCTime = *gmtime(&Time); + return DateTime(1900 + UTCTime.tm_year, UTCTime.tm_mon, UTCTime.tm_mday, UTCTime.tm_hour, UTCTime.tm_min, UTCTime.tm_sec); +} + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void usonbuilder_forcelink(); // internal diff --git a/src/zencore/include/zencore/filesystem.h b/src/zencore/include/zencore/filesystem.h index 22eb40e45..233941479 100644 --- a/src/zencore/include/zencore/filesystem.h +++ b/src/zencore/include/zencore/filesystem.h @@ -1,5 +1,4 @@ // Copyright Epic Games, Inc. All Rights Reserved. -// Copyright Epic Games, Inc. All Rights Reserved. #pragma once @@ -87,6 +86,11 @@ struct CopyFileOptions }; ZENCORE_API bool CopyFile(std::filesystem::path FromPath, std::filesystem::path ToPath, const CopyFileOptions& Options); +ZENCORE_API void CopyFile(std::filesystem::path FromPath, + std::filesystem::path ToPath, + const CopyFileOptions& Options, + std::error_code& OutError); +ZENCORE_API void CopyTree(std::filesystem::path FromPath, std::filesystem::path ToPath, const CopyFileOptions& Options); ZENCORE_API bool SupportsBlockRefCounting(std::filesystem::path Path); ZENCORE_API void PathToUtf8(const std::filesystem::path& Path, StringBuilderBase& Out); @@ -211,7 +215,10 @@ void GetDirectoryContent(const std::filesystem::path& RootDir, uint8_t Flags, Di std::string GetEnvVariable(std::string_view VariableName); +std::filesystem::path SearchPathForExecutable(std::string_view ExecutableName); + std::error_code RotateFiles(const std::filesystem::path& Filename, std::size_t MaxFiles); +std::error_code RotateDirectories(const std::filesystem::path& DirectoryName, std::size_t MaxDirectories); ////////////////////////////////////////////////////////////////////////// diff --git a/src/zencore/include/zencore/iobuffer.h b/src/zencore/include/zencore/iobuffer.h index 7accce41c..d891ed55b 100644 --- a/src/zencore/include/zencore/iobuffer.h +++ b/src/zencore/include/zencore/iobuffer.h @@ -31,6 +31,7 @@ enum class ZenContentType : uint8_t kCSS = 11, kPNG = 12, kIcon = 13, + kXML = 14, kCOUNT }; @@ -70,6 +71,8 @@ ToString(ZenContentType ContentType) return "png"sv; case ZenContentType::kIcon: return "icon"sv; + case ZenContentType::kXML: + return "xml"sv; } } diff --git a/src/zencore/include/zencore/logbase.h b/src/zencore/include/zencore/logbase.h index ad873aa51..00af68b0a 100644 --- a/src/zencore/include/zencore/logbase.h +++ b/src/zencore/include/zencore/logbase.h @@ -90,6 +90,9 @@ struct LoggerRef bool ShouldLog(int Level) const; inline operator bool() const { return SpdLogger != nullptr; } + void SetLogLevel(logging::level::LogLevel NewLogLevel); + logging::level::LogLevel GetLogLevel(); + spdlog::logger* SpdLogger = nullptr; }; diff --git a/src/zencore/include/zencore/logging.h b/src/zencore/include/zencore/logging.h index d14d1ab8d..6d44e31df 100644 --- a/src/zencore/include/zencore/logging.h +++ b/src/zencore/include/zencore/logging.h @@ -35,6 +35,10 @@ LoggerRef ErrorLog(); void SetErrorLog(std::string_view LoggerId); LoggerRef Get(std::string_view Name); +void ConfigureLogLevels(level::LogLevel Level, std::string_view Loggers); +void RefreshLogLevels(); +void RefreshLogLevels(level::LogLevel DefaultLevel); + struct LogCategory { inline LogCategory(std::string_view InCategory) : CategoryName(InCategory) {} @@ -235,6 +239,14 @@ std::string_view EmitActivitiesForLogging(StringBuilderBase& OutString); #define ZEN_LOG_SCOPE(...) ScopedLazyActivity $Activity##__LINE__([&](StringBuilderBase& Out) { Out << fmt::format(__VA_ARGS__); }) +#define ZEN_SCOPED_WARN(fmtstr, ...) \ + do \ + { \ + ExtendableStringBuilder<256> ScopeString; \ + const std::string_view Scopes = EmitActivitiesForLogging(ScopeString); \ + ZEN_LOG(Log(), zen::logging::level::Warn, fmtstr "{}", ##__VA_ARGS__, Scopes); \ + } while (false) + #define ZEN_SCOPED_ERROR(fmtstr, ...) \ do \ { \ diff --git a/src/zencore/include/zencore/process.h b/src/zencore/include/zencore/process.h new file mode 100644 index 000000000..d90a32301 --- /dev/null +++ b/src/zencore/include/zencore/process.h @@ -0,0 +1,98 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include <zencore/thread.h> +#include <zencore/zencore.h> + +#include <filesystem> + +namespace zen { + +/** Basic process abstraction + */ +class ProcessHandle +{ +public: + ZENCORE_API ProcessHandle(); + + ProcessHandle(const ProcessHandle&) = delete; + ProcessHandle& operator=(const ProcessHandle&) = delete; + + ZENCORE_API ~ProcessHandle(); + + ZENCORE_API void Initialize(int Pid); + ZENCORE_API void Initialize(void* ProcessHandle); /// Initialize with an existing handle - takes ownership of the handle + ZENCORE_API [[nodiscard]] bool IsRunning() const; + ZENCORE_API [[nodiscard]] bool IsValid() const; + ZENCORE_API bool Wait(int TimeoutMs = -1); + ZENCORE_API int WaitExitCode(); + ZENCORE_API void Terminate(int ExitCode); + ZENCORE_API void Reset(); + [[nodiscard]] inline int Pid() const { return m_Pid; } + +private: + void* m_ProcessHandle = nullptr; + int m_Pid = 0; +#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC + int m_ExitCode = -1; +#endif +}; + +/** Basic process creation + */ +struct CreateProcOptions +{ + enum + { + Flag_NewConsole = 1 << 0, + Flag_Elevated = 1 << 1, + Flag_Unelevated = 1 << 2, + }; + + const std::filesystem::path* WorkingDirectory = nullptr; + uint32_t Flags = 0; + std::filesystem::path StdoutFile; +}; + +#if ZEN_PLATFORM_WINDOWS +using CreateProcResult = void*; // handle to the process +#else +using CreateProcResult = int32_t; // pid +#endif + +ZENCORE_API CreateProcResult CreateProc(const std::filesystem::path& Executable, + std::string_view CommandLine, // should also include arg[0] (executable name) + const CreateProcOptions& Options = {}); + +/** Process monitor - monitors a list of running processes via polling + + Intended to be used to monitor a set of "sponsor" processes, where + we need to determine when none of them remain alive + + */ + +class ProcessMonitor +{ +public: + ProcessMonitor(); + ~ProcessMonitor(); + + ZENCORE_API bool IsRunning(); + ZENCORE_API void AddPid(int Pid); + ZENCORE_API bool IsActive() const; + +private: + using HandleType = void*; + + mutable RwLock m_Lock; + std::vector<HandleType> m_ProcessHandles; +}; + +ZENCORE_API bool IsProcessRunning(int pid); +ZENCORE_API int GetCurrentProcessId(); +int GetProcessId(CreateProcResult ProcId); + +void process_forcelink(); // internal + +} // namespace zen diff --git a/src/zencore/include/zencore/string.h b/src/zencore/include/zencore/string.h index e3de2224c..3aec1647d 100644 --- a/src/zencore/include/zencore/string.h +++ b/src/zencore/include/zencore/string.h @@ -809,6 +809,19 @@ ForEachStrTok(const std::string_view& Str, char Delim, Fn&& Func) ////////////////////////////////////////////////////////////////////////// +inline std::string_view +ToString(bool Value) +{ + using namespace std::literals; + if (Value) + { + return "true"sv; + } + return "false"sv; +} + +////////////////////////////////////////////////////////////////////////// + inline int32_t StrCaseCompare(const char* Lhs, const char* Rhs, int64_t Length = -1) { diff --git a/src/zencore/include/zencore/thread.h b/src/zencore/include/zencore/thread.h index 9f2671610..2d0ef7396 100644 --- a/src/zencore/include/zencore/thread.h +++ b/src/zencore/include/zencore/thread.h @@ -10,6 +10,8 @@ #include <string_view> #include <vector> +#define ZEN_USE_WINDOWS_EVENTS ZEN_PLATFORM_WINDOWS + namespace zen { void SetCurrentThreadName(std::string_view ThreadName); @@ -107,7 +109,7 @@ public: ZENCORE_API bool Wait(int TimeoutMs = -1); ZENCORE_API void Close(); -#if ZEN_PLATFORM_WINDOWS +#if ZEN_USE_WINDOWS_EVENTS inline void* GetWindowsHandle() { return m_EventHandle; } #endif @@ -204,87 +206,7 @@ private: Event Complete; }; -/** Basic process abstraction - */ -class ProcessHandle -{ -public: - ZENCORE_API ProcessHandle(); - - ProcessHandle(const ProcessHandle&) = delete; - ProcessHandle& operator=(const ProcessHandle&) = delete; - - ZENCORE_API ~ProcessHandle(); - - ZENCORE_API void Initialize(int Pid); - ZENCORE_API void Initialize(void* ProcessHandle); /// Initialize with an existing handle - takes ownership of the handle - ZENCORE_API [[nodiscard]] bool IsRunning() const; - ZENCORE_API [[nodiscard]] bool IsValid() const; - ZENCORE_API bool Wait(int TimeoutMs = -1); - ZENCORE_API int WaitExitCode(); - ZENCORE_API void Terminate(int ExitCode); - ZENCORE_API void Reset(); - [[nodiscard]] inline int Pid() const { return m_Pid; } - -private: - void* m_ProcessHandle = nullptr; - int m_Pid = 0; -}; - -/** Basic process creation - */ -struct CreateProcOptions -{ - enum - { - Flag_NewConsole = 1 << 0, - Flag_Elevated = 1 << 1, - Flag_Unelevated = 1 << 2, - }; - - const std::filesystem::path* WorkingDirectory = nullptr; - uint32_t Flags = 0; -}; - -#if ZEN_PLATFORM_WINDOWS -using CreateProcResult = void*; // handle to the process -#else -using CreateProcResult = int32_t; // pid -#endif - -ZENCORE_API CreateProcResult CreateProc(const std::filesystem::path& Executable, - std::string_view CommandLine, // should also include arg[0] (executable name) - const CreateProcOptions& Options = {}); - -/** Process monitor - monitors a list of running processes via polling - - Intended to be used to monitor a set of "sponsor" processes, where - we need to determine when none of them remain alive - - */ - -class ProcessMonitor -{ -public: - ProcessMonitor(); - ~ProcessMonitor(); - - ZENCORE_API bool IsRunning(); - ZENCORE_API void AddPid(int Pid); - ZENCORE_API bool IsActive() const; - -private: - using HandleType = void*; - - mutable RwLock m_Lock; - std::vector<HandleType> m_ProcessHandles; -}; - -ZENCORE_API bool IsProcessRunning(int pid); -ZENCORE_API int GetCurrentProcessId(); ZENCORE_API int GetCurrentThreadId(); -int GetProcessId(CreateProcResult ProcId); - ZENCORE_API void Sleep(int ms); void thread_forcelink(); // internal diff --git a/src/zencore/include/zencore/trace.h b/src/zencore/include/zencore/trace.h index 665df5808..2d4c1e610 100644 --- a/src/zencore/include/zencore/trace.h +++ b/src/zencore/include/zencore/trace.h @@ -17,6 +17,7 @@ ZEN_THIRD_PARTY_INCLUDES_START ZEN_THIRD_PARTY_INCLUDES_END #define ZEN_TRACE_CPU(x) TRACE_CPU_SCOPE(x) +#define ZEN_TRACE_CPU_FLUSH(x) TRACE_CPU_SCOPE(x, trace::CpuScopeFlags::CpuFlush) enum class TraceType { @@ -25,10 +26,10 @@ enum class TraceType None }; -void TraceInit(); +void TraceInit(std::string_view ProgramName); void TraceShutdown(); bool IsTracing(); -void TraceStart(const char* HostOrPath, TraceType Type); +void TraceStart(std::string_view ProgramName, const char* HostOrPath, TraceType Type); bool TraceStop(); #else diff --git a/src/zencore/include/zencore/windows.h b/src/zencore/include/zencore/windows.h index 0943a85ea..14026fef1 100644 --- a/src/zencore/include/zencore/windows.h +++ b/src/zencore/include/zencore/windows.h @@ -24,6 +24,7 @@ struct IUnknown; // Workaround for "combaseapi.h(229): error C2187: syntax erro # include <windows.h> # undef GetObject # undef SendMessage +# undef CopyFile ZEN_THIRD_PARTY_INCLUDES_END |