sensord: clean up sf_common.h/sensor_common.h/sensor_logs.h
[platform/core/system/sensord.git] / src / server / worker_thread.cpp
1 /*
2  * libsensord-share
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_logs.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                         ERR("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
59 bool worker_thread::start(void)
60 {
61         lock l(m_mutex);
62
63         if (m_state == WORKER_STATE_WORKING) {
64                 INFO("Worker thread is already working");
65                 return true;
66         }
67
68         if ((m_state == WORKER_STATE_INITIAL) || (m_state == WORKER_STATE_STOPPED)) {
69                 m_state = WORKER_STATE_WORKING;
70
71                 if (!m_thread_created) {
72                         thread th(&worker_thread::main, this);
73                         th.detach();
74                 }
75                 return true;
76         } else if (m_state == WORKER_STATE_PAUSED) {
77                 m_state = WORKER_STATE_WORKING;
78                 m_cond_working.notify_one();
79                 return true;
80         }
81
82         ERR("Failed to start, because current state(%d) is not for START", m_state);
83
84         return false;
85 }
86
87 bool worker_thread::stop(void)
88 {
89         lock l(m_mutex);
90
91         if (m_state == WORKER_STATE_STOPPED) {
92                 INFO("Worker thread is already stopped");
93                 return true;
94         }
95
96         if ((m_state == WORKER_STATE_WORKING) || (m_state == WORKER_STATE_PAUSED)) {
97
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         ERR("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                 INFO("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         ERR("Failed to pause, because current state(%d) is not for PAUSE", m_state);
124
125         return false;
126
127 }
128
129 bool worker_thread::resume(void)
130 {
131         lock l(m_mutex);
132
133         if (m_state == WORKER_STATE_WORKING) {
134                 INFO("Worker thread is already working");
135                 return true;
136         }
137
138         if (m_state == WORKER_STATE_PAUSED) {
139                 m_state = WORKER_STATE_WORKING;
140                 m_cond_working.notify_one();
141                 return true;
142         }
143
144         ERR("Failed to resume, because current state(%d) is not for RESUME", m_state);
145         return false;
146 }
147
148
149 /*
150  * After state changed to STOPPED, it should not access member fields,
151     because some transition funciton of STOPPED delete this pointer
152  */
153
154 void worker_thread::main(void)
155 {
156         DBG("Worker thread(0x%x) is created", std::this_thread::get_id());
157
158         transition_function(STARTED);
159
160         while (true) {
161                 worker_state_t state;
162                 state = get_state();
163
164                 if (state == WORKER_STATE_WORKING) {
165                         if (!transition_function(WORKING)) {
166                                 m_state = WORKER_STATE_STOPPED;
167                                 DBG("Worker thread(0x%x) exits from working state", std::this_thread::get_id());
168                                 m_thread_created = false;
169                                 transition_function(STOPPED);
170                                 break;
171                         }
172                         continue;
173                 }
174
175                 ulock u(m_mutex);
176
177                 if (m_state == WORKER_STATE_PAUSED) {
178                         transition_function(PAUSED);
179
180                         DBG("Worker thread(0x%x) is paused", std::this_thread::get_id());
181                         m_cond_working.wait(u);
182
183                         if (m_state == WORKER_STATE_WORKING) {
184                                 transition_function(RESUMED);
185                                 DBG("Worker thread(0x%x) is resumed", std::this_thread::get_id());
186                         } else if (m_state == WORKER_STATE_STOPPED) {
187                                 m_thread_created = false;
188                                 transition_function(STOPPED);
189                                 break;
190                         }
191                 } else if (m_state == WORKER_STATE_STOPPED) {
192                         m_thread_created = false;
193                         transition_function(STOPPED);
194                         break;
195                 }
196         }
197         INFO("Worker thread(0x%x)'s main is terminated", std::this_thread::get_id());
198 }
199
200 void worker_thread::set_started(trans_func_t func)
201 {
202         m_trans_func[STARTED] = func;
203 }
204
205 void worker_thread::set_stopped(trans_func_t func)
206 {
207         m_trans_func[STOPPED] = func;
208 }
209
210 void worker_thread::set_paused(trans_func_t func)
211 {
212         m_trans_func[PAUSED] = func;
213 }
214
215 void worker_thread::set_resumed(trans_func_t func)
216 {
217         m_trans_func[RESUMED] = func;
218 }
219
220 void worker_thread::set_working(trans_func_t func)
221 {
222         m_trans_func[WORKING] = func;
223 }
224
225 void worker_thread::set_context(void *ctx)
226 {
227         m_context = ctx;
228 }