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