From 9c8224b9312cab5645afb4d059c40473f16a3828 Mon Sep 17 00:00:00 2001 From: Reece Date: Fri, 24 Dec 2021 16:25:12 +0000 Subject: [PATCH] [+] Added TryLockGuard; AU_TRY_LOCK_GUARD_RET_DEF, AU_TRY_LOCK_GUARD, AU_TRY_LOCK_GUARD_RET_VAL, AU_TRY_LOCK_GUARD_RET_DEF [+] Added explicit AU_WHAT macro, I think people are familiar with this nomenclatures, not sure. [+] Added try catch around logger write line. I'm sure something will explode around here sooner or later --- Include/Aurora/Threading/LockGuardTry.hpp | 93 +++++++++++++++++++++++ Include/Aurora/Threading/Threading.hpp | 1 + Include/AuroraMacros.hpp | 2 + Source/Console/Hooks/Hooks.cpp | 75 ++++++++++++------ 4 files changed, 148 insertions(+), 23 deletions(-) create mode 100644 Include/Aurora/Threading/LockGuardTry.hpp diff --git a/Include/Aurora/Threading/LockGuardTry.hpp b/Include/Aurora/Threading/LockGuardTry.hpp new file mode 100644 index 00000000..84b65360 --- /dev/null +++ b/Include/Aurora/Threading/LockGuardTry.hpp @@ -0,0 +1,93 @@ +/*** + Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: LockGuard.hpp + Date: 2021-6-10 + Author: Reece +***/ +#pragma once + +namespace Aurora::Threading +{ + template + class TryLockGuard + { + private: + using Internal_t = std::remove_pointer_t; + bool bLockSuccessful; + + public: + + TryLockGuard(T &lock) + { + if constexpr (std::is_pointer_v) + { + annoying_ = lock; + } + else + { + annoying_ = &lock; + } + + if constexpr (AuIsBaseOfTemplate::value || AuIsBaseOfTemplate::value) + { + bLockSuccessful = annoying_->get()->TryLock(); + } + else + { + bLockSuccessful = annoying_->TryLock(); + } + } + + TryLockGuard(T &&lock) + { + if constexpr (std::is_pointer_v) + { + annoying_ = lock; + } + else + { + annoying_ = &lock; + } + + if constexpr (AuIsBaseOfTemplate::value || AuIsBaseOfTemplate::value) + { + bLockSuccessful = annoying_->get()->TryLock(); + } + else + { + bLockSuccessful = annoying_->TryLock(); + } + } + + ~TryLockGuard() + { + if (!bLockSuccessful) + { + return; + } + + if constexpr (AuIsBaseOfTemplate::value || AuIsBaseOfTemplate::value) + { + annoying_->get()->Unlock(); + } + else + { + annoying_->Unlock(); + } + } + + const bool Locked() const + { + return bLockSuccessful; + } + private: + std::conditional_t, T, T*> annoying_; + }; + + #define AU_TRY_LOCK_GUARD(variable) Aurora::Threading::TryLockGuard AU_CONCAT(__stack_lock, __COUNTER__) (variable); + #define AU_TRY_LOCK_GUARD_RET_(variable, value, counter) Aurora::Threading::TryLockGuard AU_CONCAT(__stack_lock, counter) (variable); if (!(AU_CONCAT(__stack_lock, counter).Locked())) return value; + #define AU_TRY_LOCK_GUARD_RET_VAL(variable, value) AU_TRY_LOCK_GUARD_RET_(variable, value, AU_WHAT(__COUNTER__)) + #define AU_TRY_LOCK_GUARD_RET_DEF(variable) AU_TRY_LOCK_GUARD_RET_VAL(variable, {}) + #define AU_TRY_LOCK_GUARD_RET(variable) AU_TRY_LOCK_GUARD_RET_VAL(variable, ) +} \ No newline at end of file diff --git a/Include/Aurora/Threading/Threading.hpp b/Include/Aurora/Threading/Threading.hpp index ce2905ac..ba530e75 100644 --- a/Include/Aurora/Threading/Threading.hpp +++ b/Include/Aurora/Threading/Threading.hpp @@ -16,6 +16,7 @@ #include "Sleep.hpp" #include "LockGuard.hpp" +#include "LockGuardTry.hpp" #include "Threads/Threads.hpp" diff --git a/Include/AuroraMacros.hpp b/Include/AuroraMacros.hpp index 6f2c1e87..75f9f790 100644 --- a/Include/AuroraMacros.hpp +++ b/Include/AuroraMacros.hpp @@ -25,6 +25,8 @@ #define AU_TEMPLATE_ENABLE_WHEN(...) typename std::enable_if<__VA_ARGS__>::type* = nullptr #endif +#define AU_WHAT(n) n + /// @hideinitializer #define AU_STRINGIFY_(in) #in #define AU_STRINGIFY(in) AU_STRINGIFY_(in) diff --git a/Source/Console/Hooks/Hooks.cpp b/Source/Console/Hooks/Hooks.cpp index 92c52683..fc014d53 100644 --- a/Source/Console/Hooks/Hooks.cpp +++ b/Source/Console/Hooks/Hooks.cpp @@ -37,40 +37,69 @@ namespace Aurora::Console::Hooks gExternalLineProcessor = subscriber; } + static void WriteLoggerFailedWarning() + { + static std::string kLoggerError = "Something went from while dispatching a log line\n"; + Console::WriteStdOut(kLoggerError.data(), kLoggerError.size()); + + #if defined(AURORA_IS_MODERNNT_DERIVED) + OutputDebugStringA(kLoggerError.c_str()); + #endif + } + + static void TryWrite(const ConsoleMessage &msg) + { + for (const auto &callback : gLineFunctionalCallbacks) + { + try + { + callback(msg); + } + catch (...) + { + WriteLoggerFailedWarning(); + } + } + + for (const auto &sub : gLineSubscribers) + { + try + { + sub->OnMessage(msg); + } + catch (...) + { + WriteLoggerFailedWarning(); + } + } + } + void WriteLine(const ConsoleMessage &msg) { AU_LOCK_GUARD(gMutex); - if (msg.line.find('\n') == AuString::npos) [[likely]] + try { - for (const auto &callback : gLineFunctionalCallbacks) + if (msg.line.find('\n') == AuString::npos) [[likely]] { - callback(msg); + TryWrite(msg); } - - for (const auto &sub : gLineSubscribers) + else [[unlikely]] { - sub->OnMessage(msg); + Parse::SplitNewlines(msg.line, + [&](const AuString &line) + { + ConsoleMessage dup = msg; + dup.line = line; + + TryWrite(msg); + }); } } - else [[unlikely]] + catch (...) { - Parse::SplitNewlines(msg.line, - [&](const AuString &line) - { - ConsoleMessage dup = msg; - dup.line = line; - - for (const auto &callback : gLineFunctionalCallbacks) - { - callback(dup); - } - - for (const auto &sub : gLineSubscribers) - { - sub->OnMessage(dup); - } - }); + // Loggers experiencing something fucky is a liablity + WriteLoggerFailedWarning(); } }