summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/common_funcs.h6
-rw-r--r--src/common/fiber.cpp23
-rw-r--r--src/common/fiber.h2
-rw-r--r--src/common/misc.cpp44
4 files changed, 48 insertions, 27 deletions
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h
index 71b64e32a..4ace2cd33 100644
--- a/src/common/common_funcs.h
+++ b/src/common/common_funcs.h
@@ -52,9 +52,13 @@ __declspec(dllimport) void __stdcall DebugBreak(void);
52// Generic function to get last error message. 52// Generic function to get last error message.
53// Call directly after the command or use the error num. 53// Call directly after the command or use the error num.
54// This function might change the error code. 54// This function might change the error code.
55// Defined in Misc.cpp. 55// Defined in misc.cpp.
56[[nodiscard]] std::string GetLastErrorMsg(); 56[[nodiscard]] std::string GetLastErrorMsg();
57 57
58// Like GetLastErrorMsg(), but passing an explicit error code.
59// Defined in misc.cpp.
60[[nodiscard]] std::string NativeErrorToString(int e);
61
58#define DECLARE_ENUM_FLAG_OPERATORS(type) \ 62#define DECLARE_ENUM_FLAG_OPERATORS(type) \
59 [[nodiscard]] constexpr type operator|(type a, type b) noexcept { \ 63 [[nodiscard]] constexpr type operator|(type a, type b) noexcept { \
60 using T = std::underlying_type_t<type>; \ 64 using T = std::underlying_type_t<type>; \
diff --git a/src/common/fiber.cpp b/src/common/fiber.cpp
index 3c1eefcb7..39532ff58 100644
--- a/src/common/fiber.cpp
+++ b/src/common/fiber.cpp
@@ -116,16 +116,19 @@ void Fiber::Rewind() {
116 boost::context::detail::jump_fcontext(impl->rewind_context, this); 116 boost::context::detail::jump_fcontext(impl->rewind_context, this);
117} 117}
118 118
119void Fiber::YieldTo(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to) { 119void Fiber::YieldTo(std::weak_ptr<Fiber> weak_from, Fiber& to) {
120 ASSERT_MSG(from != nullptr, "Yielding fiber is null!"); 120 to.impl->guard.lock();
121 ASSERT_MSG(to != nullptr, "Next fiber is null!"); 121 to.impl->previous_fiber = weak_from.lock();
122 to->impl->guard.lock(); 122
123 to->impl->previous_fiber = from; 123 auto transfer = boost::context::detail::jump_fcontext(to.impl->context, &to);
124 auto transfer = boost::context::detail::jump_fcontext(to->impl->context, to.get()); 124
125 ASSERT(from->impl->previous_fiber != nullptr); 125 // "from" might no longer be valid if the thread was killed
126 from->impl->previous_fiber->impl->context = transfer.fctx; 126 if (auto from = weak_from.lock()) {
127 from->impl->previous_fiber->impl->guard.unlock(); 127 ASSERT(from->impl->previous_fiber != nullptr);
128 from->impl->previous_fiber.reset(); 128 from->impl->previous_fiber->impl->context = transfer.fctx;
129 from->impl->previous_fiber->impl->guard.unlock();
130 from->impl->previous_fiber.reset();
131 }
129} 132}
130 133
131std::shared_ptr<Fiber> Fiber::ThreadToFiber() { 134std::shared_ptr<Fiber> Fiber::ThreadToFiber() {
diff --git a/src/common/fiber.h b/src/common/fiber.h
index f7f587f8c..f2a8ff29a 100644
--- a/src/common/fiber.h
+++ b/src/common/fiber.h
@@ -41,7 +41,7 @@ public:
41 41
42 /// Yields control from Fiber 'from' to Fiber 'to' 42 /// Yields control from Fiber 'from' to Fiber 'to'
43 /// Fiber 'from' must be the currently running fiber. 43 /// Fiber 'from' must be the currently running fiber.
44 static void YieldTo(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to); 44 static void YieldTo(std::weak_ptr<Fiber> weak_from, Fiber& to);
45 [[nodiscard]] static std::shared_ptr<Fiber> ThreadToFiber(); 45 [[nodiscard]] static std::shared_ptr<Fiber> ThreadToFiber();
46 46
47 void SetRewindPoint(std::function<void(void*)>&& rewind_func, void* rewind_param); 47 void SetRewindPoint(std::function<void(void*)>&& rewind_func, void* rewind_param);
diff --git a/src/common/misc.cpp b/src/common/misc.cpp
index 1d5393597..495385b9e 100644
--- a/src/common/misc.cpp
+++ b/src/common/misc.cpp
@@ -12,27 +12,41 @@
12 12
13#include "common/common_funcs.h" 13#include "common/common_funcs.h"
14 14
15// Generic function to get last error message. 15std::string NativeErrorToString(int e) {
16// Call directly after the command or use the error num.
17// This function might change the error code.
18std::string GetLastErrorMsg() {
19 static constexpr std::size_t buff_size = 255;
20 char err_str[buff_size];
21
22#ifdef _WIN32 16#ifdef _WIN32
23 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, GetLastError(), 17 LPSTR err_str;
24 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err_str, buff_size, nullptr); 18
25 return std::string(err_str, buff_size); 19 DWORD res = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER |
26#elif defined(__GLIBC__) && (_GNU_SOURCE || (_POSIX_C_SOURCE < 200112L && _XOPEN_SOURCE < 600)) 20 FORMAT_MESSAGE_IGNORE_INSERTS,
21 nullptr, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
22 reinterpret_cast<LPSTR>(&err_str), 1, nullptr);
23 if (!res) {
24 return "(FormatMessageA failed to format error)";
25 }
26 std::string ret(err_str);
27 LocalFree(err_str);
28 return ret;
29#else
30 char err_str[255];
31#if defined(__GLIBC__) && (_GNU_SOURCE || (_POSIX_C_SOURCE < 200112L && _XOPEN_SOURCE < 600))
27 // Thread safe (GNU-specific) 32 // Thread safe (GNU-specific)
28 const char* str = strerror_r(errno, err_str, buff_size); 33 const char* str = strerror_r(e, err_str, sizeof(err_str));
29 return std::string(str); 34 return std::string(str);
30#else 35#else
31 // Thread safe (XSI-compliant) 36 // Thread safe (XSI-compliant)
32 const int success = strerror_r(errno, err_str, buff_size); 37 int second_err = strerror_r(e, err_str, sizeof(err_str));
33 if (success != 0) { 38 if (second_err != 0) {
34 return {}; 39 return "(strerror_r failed to format error)";
35 } 40 }
36 return std::string(err_str); 41 return std::string(err_str);
42#endif // GLIBC etc.
43#endif // _WIN32
44}
45
46std::string GetLastErrorMsg() {
47#ifdef _WIN32
48 return NativeErrorToString(GetLastError());
49#else
50 return NativeErrorToString(errno);
37#endif 51#endif
38} 52}