1 /* Copyright (c) 2015, 2020 The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation, nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29 #include <sys/prctl.h>
30 #include <LocThread.h>
31 #include <string.h>
32 #include <string>
33 #include <thread>
34 #include <loc_pla.h>
35
36 using std::weak_ptr;
37 using std::shared_ptr;
38 using std::thread;
39 using std::string;
40
41 namespace loc_util {
42
43 class LocThreadDelegate {
44 static const char defaultThreadName[];
45 weak_ptr<LocRunnable> mRunnable;
46 thread mThread;
47 LocThreadDelegate(const string tName, shared_ptr<LocRunnable> r);
48 public:
~LocThreadDelegate()49 ~LocThreadDelegate() {
50 shared_ptr<LocRunnable> runnable = mRunnable.lock();
51 if (nullptr != runnable) {
52 runnable->interrupt();
53 }
54 }
55 inline static LocThreadDelegate* create(const char* tName, shared_ptr<LocRunnable> runnable);
56 };
57
58 const char LocThreadDelegate::defaultThreadName[] = "LocThread";
59
create(const char * tName,shared_ptr<LocRunnable> runnable)60 LocThreadDelegate* LocThreadDelegate::create(const char* tName, shared_ptr<LocRunnable> runnable) {
61 LocThreadDelegate* threadDelegate = nullptr;
62
63 if (nullptr != runnable) {
64 if (!tName) {
65 tName = defaultThreadName;
66 }
67
68 char lname[16];
69 auto nameSize = strlen(tName) + 1;
70 int len = std::min(sizeof(lname), nameSize) - 1;
71 memcpy(lname, tName, len);
72 lname[len] = 0;
73
74 threadDelegate = new LocThreadDelegate(lname, runnable);
75 }
76
77 return threadDelegate;
78 }
79
LocThreadDelegate(const string tName,shared_ptr<LocRunnable> runnable)80 LocThreadDelegate::LocThreadDelegate(const string tName, shared_ptr<LocRunnable> runnable) :
81 mRunnable(runnable),
82 mThread([tName, runnable] {
83 prctl(PR_SET_NAME, tName.c_str(), 0, 0, 0);
84 runnable->prerun();
85 while (runnable->run());
86 runnable->postrun();
87 }) {
88
89 mThread.detach();
90 }
91
92
93
start(const char * tName,shared_ptr<LocRunnable> runnable)94 bool LocThread::start(const char* tName, shared_ptr<LocRunnable> runnable) {
95 bool success = false;
96 if (!mThread) {
97 mThread = LocThreadDelegate::create(tName, runnable);
98 // true only if thread is created successfully
99 success = (NULL != mThread);
100 }
101 return success;
102 }
103
stop()104 void LocThread::stop() {
105 if (nullptr != mThread) {
106 delete mThread;
107 mThread = nullptr;
108 }
109 }
110
111 } // loc_util
112