1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <folly/system/ThreadName.h>
18 
19 #include <thread>
20 
21 #include <folly/ScopeGuard.h>
22 #include <folly/portability/GTest.h>
23 #include <folly/synchronization/Baton.h>
24 
25 using namespace std;
26 using namespace folly;
27 
28 namespace {
29 
30 const bool expectedSetOtherThreadNameResult = folly::canSetOtherThreadName();
31 const bool expectedSetSelfThreadNameResult = folly::canSetCurrentThreadName();
32 constexpr StringPiece kThreadName{"rockin-thread"};
33 
34 } // namespace
35 
TEST(ThreadName,getCurrentThreadName)36 TEST(ThreadName, getCurrentThreadName) {
37   thread th([] {
38     EXPECT_EQ(expectedSetSelfThreadNameResult, setThreadName(kThreadName));
39     if (expectedSetSelfThreadNameResult) {
40       EXPECT_EQ(kThreadName.toString(), *getCurrentThreadName());
41     }
42   });
43   SCOPE_EXIT { th.join(); };
44 }
45 
46 #if FOLLY_HAVE_PTHREAD
TEST(ThreadName,setThreadName_other_pthread)47 TEST(ThreadName, setThreadName_other_pthread) {
48   Baton<> handle_set;
49   Baton<> let_thread_end;
50   pthread_t handle;
51   thread th([&] {
52     handle = pthread_self();
53     handle_set.post();
54     let_thread_end.wait();
55   });
56   SCOPE_EXIT { th.join(); };
57   handle_set.wait();
58   SCOPE_EXIT { let_thread_end.post(); };
59 #ifndef __XROS__
60   EXPECT_EQ(
61       expectedSetOtherThreadNameResult, setThreadName(handle, kThreadName));
62 #else
63   // XROS portability pthread implementation supports setting other pthread
64   // name. However setting name of another `std::thread` is not supported, hence
65   // `canSetOtherThreadName()` is more pessimistic than `setThreadName()`.
66   EXPECT_FALSE(expectedSetOtherThreadNameResult);
67   EXPECT_TRUE(setThreadName(handle, kThreadName));
68 #endif
69 }
70 #endif
71 
TEST(ThreadName,setThreadName_other_id)72 TEST(ThreadName, setThreadName_other_id) {
73   Baton<> let_thread_end;
74   thread th([&] { let_thread_end.wait(); });
75   SCOPE_EXIT { th.join(); };
76   SCOPE_EXIT { let_thread_end.post(); };
77   EXPECT_EQ(
78       expectedSetOtherThreadNameResult,
79       setThreadName(th.get_id(), kThreadName));
80   if (expectedSetOtherThreadNameResult) {
81     EXPECT_EQ(*getThreadName(th.get_id()), kThreadName);
82   }
83 }
84