9 #include "quill/core/Attributes.h" 10 #include "quill/core/QuillError.h" 17 #if !defined(WIN32_LEAN_AND_MEAN) 18 #define WIN32_LEAN_AND_MEAN 21 #if !defined(NOMINMAX) 30 #elif defined(__APPLE__) 31 #include <mach/thread_act.h> 32 #include <mach/thread_policy.h> 34 #elif defined(__NetBSD__) 38 #elif defined(__FreeBSD__) 39 #include <pthread_np.h> 42 #elif defined(__DragonFly__) 43 #include <pthread_np.h> 46 #elif defined(__OpenBSD__) 47 #include <pthread_np.h> 52 #include <sys/syscall.h> 60 #if defined(_WIN32) && defined(_MSC_VER) 67 QUILL_NODISCARD
inline std::wstring s2ws(std::string
const& str) noexcept
70 #pragma warning(disable : 4996) 72 using convert_t = std::codecvt_utf8_utf16<wchar_t>;
73 std::wstring_convert<convert_t, wchar_t> converter;
74 return converter.from_bytes(str);
84 QUILL_NODISCARD
inline std::string ws2s(std::wstring
const& wstr) noexcept
87 #pragma warning(disable : 4996) 89 using convert_t = std::codecvt_utf8_utf16<wchar_t>;
90 std::wstring_convert<convert_t, wchar_t> converter;
91 return converter.to_bytes(wstr);
97 template <
typename ReturnT,
typename Signature,
typename... Args>
98 ReturnT callRunTimeDynamicLinkedFunction(std::string
const& dll_name,
99 std::string
const& function_name, Args... args)
106 const HINSTANCE hinstLibrary = LoadLibraryW(s2ws(dll_name).c_str());
108 const HINSTANCE hinstLibrary = LoadLibraryA(dll_name.c_str());
111 if (QUILL_UNLIKELY(hinstLibrary ==
nullptr))
113 QUILL_THROW(
QuillError{std::string{
"Failed to load library " + dll_name}});
117 FARPROC proc_address = GetProcAddress(hinstLibrary, function_name.c_str());
119 if (QUILL_UNLIKELY(proc_address ==
nullptr))
121 FreeLibrary(hinstLibrary);
122 QUILL_THROW(
QuillError{std::string{
"Failed to call " + function_name +
" " + dll_name}});
127 memcpy(&callable, &proc_address,
sizeof(proc_address));
129 ReturnT
const hr = callable(static_cast<Args&&>(args)...);
130 BOOL
const fFreeResult = FreeLibrary(hinstLibrary);
132 if (QUILL_UNLIKELY(!fFreeResult))
134 QUILL_THROW(
QuillError{std::string{
"Failed to free library " + dll_name}});
147 QUILL_NODISCARD QUILL_EXPORT QUILL_ATTRIBUTE_USED
inline std::string
get_thread_name()
149 #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(__ANDROID__) || \ 150 defined(QUILL_NO_THREAD_NAME_SUPPORT) 152 return std::string{
"ThreadNameDisabled"};
153 #elif defined(_WIN32) 154 PWSTR data =
nullptr;
156 typedef HRESULT(WINAPI * GetThreadDescriptionSignature)(HANDLE, PWSTR*);
157 HRESULT hr = callRunTimeDynamicLinkedFunction<HRESULT, GetThreadDescriptionSignature>(
158 "KernelBase.dll",
"GetThreadDescription", GetCurrentThread(), &data);
162 QUILL_THROW(
QuillError{
"Failed to get thread name"});
165 if (QUILL_UNLIKELY(data ==
nullptr))
167 QUILL_THROW(
QuillError{
"Failed to get thread name. Invalid data."});
170 std::wstring
const wide_name{data, wcsnlen_s(data, 256)};
172 return ws2s(wide_name);
175 char thread_name[16] = {
'\0'};
176 #if defined(__OpenBSD__) || defined(__FreeBSD__) 177 pthread_get_name_np(pthread_self(), &thread_name[0], 16);
179 auto res = pthread_getname_np(pthread_self(), &thread_name[0], 16);
182 QUILL_THROW(
QuillError{
"Failed to get thread name. error: " + std::to_string(res)});
185 return std::string{&thread_name[0], strlen(&thread_name[0])};
193 QUILL_NODISCARD QUILL_EXPORT QUILL_ATTRIBUTE_USED
inline uint32_t
get_thread_id() noexcept
195 #if defined(__CYGWIN__) 198 #elif defined(_WIN32) 199 return static_cast<uint32_t
>(GetCurrentThreadId());
200 #elif defined(__linux__) 201 return static_cast<uint32_t
>(::syscall(SYS_gettid));
202 #elif defined(__APPLE__) 204 pthread_threadid_np(
nullptr, &tid64);
205 return static_cast<uint32_t
>(tid64);
206 #elif defined(__NetBSD__) 207 return static_cast<uint32_t
>(_lwp_self());
208 #elif defined(__FreeBSD__) 211 return static_cast<uint32_t
>(lwpid);
212 #elif defined(__DragonFly__) 213 return static_cast<uint32_t
>(lwp_gettid());
214 #elif defined(__OpenBSD__) 215 return static_cast<uint32_t
>(getthrid());
217 return reinterpret_cast<uintptr_t
>(pthread_self());
QUILL_NODISCARD QUILL_EXPORT QUILL_ATTRIBUTE_USED std::string get_thread_name()
Returns the name of the thread.
Definition: ThreadUtilities.h:147
Setups a signal handler to handle fatal signals.
Definition: BackendManager.h:24
custom exception
Definition: QuillError.h:45
QUILL_NODISCARD QUILL_EXPORT QUILL_ATTRIBUTE_USED uint32_t get_thread_id() noexcept
Returns the os assigned ID of the thread.
Definition: ThreadUtilities.h:193