• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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