From 5cef863eee8a03e1b6b137fb283d6fe703f35d2d Mon Sep 17 00:00:00 2001 From: Christopher Dykes Date: Thu, 4 May 2017 16:31:01 -0700 Subject: [PATCH] Add support for getting the current thread's name Summary: It's primarily for use in testing, but is useful for log output as well. Reviewed By: yfeldblum Differential Revision: D4943072 fbshipit-source-id: 0ca259d6c90f439e733a6179e7cba85dcd1ec9e7 --- folly/ThreadName.cpp | 29 +++++++++++++++++++++++++++-- folly/ThreadName.h | 6 ++++++ folly/test/ThreadNameTest.cpp | 11 +++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/folly/ThreadName.cpp b/folly/ThreadName.cpp index a24a6b8b..97db551f 100644 --- a/folly/ThreadName.cpp +++ b/folly/ThreadName.cpp @@ -57,6 +57,30 @@ bool canSetOtherThreadName() { #endif } +static constexpr size_t kMaxThreadNameLength = 16; + +Optional getCurrentThreadName() { +#if !FOLLY_HAVE_PTHREAD + return Optional(); +#else +#if FOLLY_HAS_PTHREAD_SETNAME_NP_THREAD_NAME + std::array buf; + if (pthread_getname_np(pthread_self(), buf.data(), buf.size()) != 0) { + return Optional(); + } + return make_optional(std::string(buf.data())); +#elif FOLLY_HAS_PTHREAD_SETNAME_NP_NAME + std::array buf; + if (pthread_getname_np(buf.data(), buf.size()) != 0) { + return Optional(); + } + return make_optional(std::string(buf.data())); +#else + return Optional(); +#endif +#endif +} + bool setThreadName(std::thread::id tid, StringPiece name) { #if !FOLLY_HAVE_PTHREAD || _WIN32 return false; @@ -73,13 +97,14 @@ bool setThreadName(std::thread::id tid, StringPiece name) { // extract it. pthread_t id; std::memcpy(&id, &tid, sizeof(id)); + auto trimmedName = name.fbstr().substr(0, kMaxThreadNameLength - 1); #if FOLLY_HAS_PTHREAD_SETNAME_NP_THREAD_NAME - return 0 == pthread_setname_np(id, name.fbstr().substr(0, 15).c_str()); + return 0 == pthread_setname_np(id, trimmedName.c_str()); #elif FOLLY_HAS_PTHREAD_SETNAME_NP_NAME // Since OS X 10.6 it is possible for a thread to set its own name, // but not that of some other thread. if (pthread_equal(pthread_self(), id)) { - return 0 == pthread_setname_np(name.fbstr().c_str()); + return 0 == pthread_setname_np(trimmedName.c_str()); } return false; #else diff --git a/folly/ThreadName.h b/folly/ThreadName.h index b55793ce..d78e2fa1 100644 --- a/folly/ThreadName.h +++ b/folly/ThreadName.h @@ -16,8 +16,10 @@ #pragma once +#include #include +#include #include #include #include @@ -33,6 +35,10 @@ bool canSetCurrentThreadName(); * threads other than the one currently executing. */ bool canSetOtherThreadName(); +/** + * Get the name of the current string, or nothing if an error occurs. + */ +Optional getCurrentThreadName(); bool setThreadName(std::thread::id tid, StringPiece name); #if FOLLY_HAVE_PTHREAD diff --git a/folly/test/ThreadNameTest.cpp b/folly/test/ThreadNameTest.cpp index 57eae214..b804bbb1 100644 --- a/folly/test/ThreadNameTest.cpp +++ b/folly/test/ThreadNameTest.cpp @@ -27,6 +27,17 @@ using namespace folly; static bool expectedSetOtherThreadNameResult = folly::canSetOtherThreadName(); static bool expectedSetSelfThreadNameResult = folly::canSetCurrentThreadName(); +TEST(ThreadName, getCurrentThreadName) { + static constexpr StringPiece kThreadName{"rockin-thread"}; + thread th([] { + EXPECT_EQ(expectedSetSelfThreadNameResult, setThreadName(kThreadName)); + if (expectedSetSelfThreadNameResult) { + EXPECT_EQ(kThreadName.toString(), getCurrentThreadName().value()); + } + }); + SCOPE_EXIT { th.join(); }; +} + TEST(ThreadName, setThreadName_self) { thread th([] { EXPECT_EQ(expectedSetSelfThreadNameResult, setThreadName("rockin-thread")); -- 2.34.1