sensord: fix incorrect return type
[platform/core/system/sensord.git] / src / server / worker_thread.cpp
1 /*
2  * sensord
3  *
4  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <sensor_log.h>
21 #include <worker_thread.h>
22 #include <thread>
23
24 using std::thread;
25
26 worker_thread::worker_thread()
27 : m_state(WORKER_STATE_INITIAL)
28 , m_context(NULL)
29 , m_thread_created(false)
30 {
31         for (int i = 0; i < TRANS_FUNC_CNT; ++i)
32                 m_trans_func[i] = NULL;
33 }
34
35 worker_thread::~worker_thread()
36 {
37         stop();
38 }
39
40 bool worker_thread::transition_function(trans_func_index index)
41 {
42         if (m_trans_func[index] != NULL) {
43                 if (!m_trans_func[index](m_context)) {
44                         _W("Transition[%d] function returning false", index);
45                         return false;
46                 }
47         }
48
49         return true;
50 }
51
52 worker_thread::worker_state_t worker_thread::get_state(void)
53 {
54         lock l(m_mutex);
55         return m_state;
56 }
57
58 bool worker_thread::start(void)
59 {
60         lock l(m_mutex);
61
62         if (m_state == WORKER_STATE_WORKING) {
63                 _I("Worker thread is already working");
64                 return true;
65         }
66
67         if ((m_state == WORKER_STATE_INITIAL) || (m_state == WORKER_STATE_STOPPED)) {
68                 m_state = WORKER_STATE_WORKING;
69
70                 if (!m_thread_created) {
71                         thread th(&worker_thread::main, this);
72                         th.detach();
73                 }
74                 return true;
75         }
76
77         if (m_state == WORKER_STATE_PAUSED) {
78                 m_state = WORKER_STATE_WORKING;
79                 m_cond_working.notify_one();
80                 return true;
81         }
82
83         _E("Failed to start, because current state(%d) is not for START", m_state);
84
85         return false;
86 }
87
88 bool worker_thread::stop(void)
89 {
90         lock l(m_mutex);
91
92         if (m_state == WORKER_STATE_STOPPED) {
93                 _I("Worker thread is already stopped");
94                 return true;
95         }
96
97         if ((m_state == WORKER_STATE_WORKING) || (m_state == WORKER_STATE_PAUSED)) {
98                 if (m_state == WORKER_STATE_PAUSED)
99                         m_cond_working.notify_one();
100
101                 m_state = WORKER_STATE_STOPPED;
102                 return true;
103         }
104
105         _E("Failed to stop, because current state(%d) is not for STOP", m_state);
106         return false;
107 }
108
109 bool worker_thread::pause(void)
110 {
111         lock l(m_mutex);
112
113         if (m_state == WORKER_STATE_PAUSED) {
114                 _I("Worker thread is already paused");
115                 return true;
116         }
117
118         if (m_state == WORKER_STATE_WORKING) {
119                 m_state = WORKER_STATE_PAUSED;
120                 return true;
121         }
122
123         _E("Failed to pause, because current state(%d) is not for PAUSE", m_state);
124
125         return false;
126 }
127
128 bool worker_thread::resume(void)
129 {
130         lock l(m_mutex);
131
132         if (m_state == WORKER_STATE_WORKING) {
133                 _I("Worker thread is already working");
134                 return true;
135         }
136
137         if (m_state == WORKER_STATE_PAUSED) {
138                 m_state = WORKER_STATE_WORKING;
139                 m_cond_working.notify_one();
140                 return true;
141         }
142
143         _E("Failed to resume, because current state(%d) is not for RESUME", m_state);
144         return false;
145 }
146
147 /*
148  * After state changed to STOPPED, it should not access member fields,
149     because some transition funciton of STOPPED delete this pointer
150  */
151
152 void worker_thread::main(void)
153 {
154         _D("Worker thread(%#x) is created", std::this_thread::get_id());
155
156         transition_function(STARTED);
157
158         while (true) {
159                 worker_state_t state;
160                 state = get_state();
161
162                 if (state == WORKER_STATE_WORKING) {
163                         if (!transition_function(WORKING)) {
164                                 m_state = WORKER_STATE_STOPPED;
165                                 _D("Worker thread(%#x) exits from working state", std::this_thread::get_id());
166                                 m_thread_created = false;
167                                 transition_function(STOPPED);
168                                 break;
169                         }
170                         continue;
171                 }
172
173                 ulock u(m_mutex);
174
175                 if (m_state == WORKER_STATE_PAUSED) {
176                         transition_function(PAUSED);
177
178                         _D("Worker thread(%#x) is paused", std::this_thread::get_id());
179                         m_cond_working.wait(u);
180
181                         if (m_state == WORKER_STATE_WORKING) {
182                                 transition_function(RESUMED);
183                                 _D("Worker thread(%#x) is resumed", std::this_thread::get_id());
184                         } else if (m_state == WORKER_STATE_STOPPED) {
185                                 m_thread_created = false;
186                                 transition_function(STOPPED);
187                                 break;
188                         }
189                 } else if (m_state == WORKER_STATE_STOPPED) {
190                         m_thread_created = false;
191                         transition_function(STOPPED);
192                         break;
193                 }
194         }
195         _I("Worker thread(%#x)'s main is terminated", std::this_thread::get_id());
196 }
197
198 void worker_thread::set_started(trans_func_t func)
199 {
200         m_trans_func[STARTED] = func;
201 }
202
203 void worker_thread::set_stopped(trans_func_t func)
204 {
205         m_trans_func[STOPPED] = func;
206 }
207
208 void worker_thread::set_paused(trans_func_t func)
209 {
210         m_trans_func[PAUSED] = func;
211 }
212
213 void worker_thread::set_resumed(trans_func_t func)
214 {
215         m_trans_func[RESUMED] = func;
216 }
217
218 void worker_thread::set_working(trans_func_t func)
219 {
220         m_trans_func[WORKING] = func;
221 }
222
223 void worker_thread::set_context(void *ctx)
224 {
225         m_context = ctx;
226 }