rippled
Loading...
Searching...
No Matches
beast_CurrentThreadName_test.cpp
1#include <xrpl/beast/core/CurrentThreadName.h>
2#include <xrpl/beast/unit_test.h>
3
4#include <boost/predef/os.h>
5
6#include <thread>
7
8namespace xrpl {
9namespace test {
10
12{
13private:
14 static void
16 std::string myName,
18 std::atomic<int>* state)
19 {
20 // Verify that upon creation a thread has no name.
21 auto const initialThreadName = beast::getCurrentThreadName();
22
23 // Set the new name.
25
26 // Indicate to caller that the name is set.
27 *state = 1;
28
29 // If there is an initial thread name then we failed.
30 if (!initialThreadName.empty())
31 return;
32
33 // Wait until all threads have their names.
34 while (!*stop)
35 ;
36
37 // Make sure the thread name that we set before is still there
38 // (not overwritten by, for instance, another thread).
39 if (beast::getCurrentThreadName() == myName)
40 *state = 2;
41 }
42#if BOOST_OS_LINUX
43 // Helper function to test a specific name.
44 // It creates a thread, sets the name, and checks if the OS-level
45 // name matches the expected (potentially truncated) name.
46 void
47 testName(std::string const& nameToSet, std::string const& expectedName)
48 {
49 std::thread t([&] {
51
52 // Initialize buffer to be safe.
53 char actualName[beast::maxThreadNameLength + 1] = {};
54 pthread_getname_np(pthread_self(), actualName, sizeof(actualName));
55
56 BEAST_EXPECT(std::string(actualName) == expectedName);
57 });
58 t.join();
59 }
60#endif
61
62public:
63 void
64 run() override
65 {
66 // Make two different threads with two different names.
67 // Make sure that the expected thread names are still there
68 // when the thread exits.
69 {
70 std::atomic<bool> stop{false};
71
72 std::atomic<int> stateA{0};
73 std::thread tA(exerciseName, "tA", &stop, &stateA);
74
75 std::atomic<int> stateB{0};
76 std::thread tB(exerciseName, "tB", &stop, &stateB);
77
78 // Wait until both threads have set their names.
79 while (stateA == 0 || stateB == 0)
80 ;
81
82 stop = true;
83 tA.join();
84 tB.join();
85
86 // Both threads should still have the expected name when they exit.
87 BEAST_EXPECT(stateA == 2);
88 BEAST_EXPECT(stateB == 2);
89 }
90#if BOOST_OS_LINUX
91 // On Linux, verify that thread names longer than 15 characters
92 // are truncated to 15 characters (the 16th character is reserved for
93 // the null terminator).
94 {
95 testName(
96 "123456789012345",
97 "123456789012345"); // 15 chars, no truncation
98 testName(
99 "1234567890123456", "123456789012345"); // 16 chars, truncated
100 testName(
101 "ThisIsAVeryLongThreadNameExceedingLimit",
102 "ThisIsAVeryLong"); // 39 chars, truncated
103 testName("", ""); // empty name
104 testName("short", "short"); // short name, no truncation
105 }
106#endif
107 }
108};
109
110BEAST_DEFINE_TESTSUITE(CurrentThreadName, beast, beast);
111
112} // namespace test
113} // namespace xrpl
A testsuite class.
Definition suite.h:52
static void exerciseName(std::string myName, std::atomic< bool > *stop, std::atomic< int > *state)
T join(T... args)
void setCurrentThreadName(std::string_view newThreadName)
Changes the name of the caller thread.
std::string getCurrentThreadName()
Returns the name of the caller thread.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6