4 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <sensor_log.h>
21 #include <worker_thread.h>
26 worker_thread::worker_thread()
27 : m_state(WORKER_STATE_INITIAL)
29 , m_thread_created(false)
31 for (int i = 0; i < TRANS_FUNC_CNT; ++i)
32 m_trans_func[i] = NULL;
35 worker_thread::~worker_thread()
40 bool worker_thread::transition_function(trans_func_index index)
42 if (m_trans_func[index] != NULL) {
43 if (!m_trans_func[index](m_context)) {
44 _W("Transition[%d] function returning false", index);
52 worker_thread::worker_state_t worker_thread::get_state(void)
58 bool worker_thread::start(void)
62 if (m_state == WORKER_STATE_WORKING) {
63 _I("Worker thread is already working");
67 if ((m_state == WORKER_STATE_INITIAL) || (m_state == WORKER_STATE_STOPPED)) {
68 m_state = WORKER_STATE_WORKING;
70 if (!m_thread_created) {
71 thread th(&worker_thread::main, this);
77 if (m_state == WORKER_STATE_PAUSED) {
78 m_state = WORKER_STATE_WORKING;
79 m_cond_working.notify_one();
83 _E("Failed to start, because current state(%d) is not for START", m_state);
88 bool worker_thread::stop(void)
92 if (m_state == WORKER_STATE_STOPPED) {
93 _I("Worker thread is already stopped");
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();
101 m_state = WORKER_STATE_STOPPED;
105 _E("Failed to stop, because current state(%d) is not for STOP", m_state);
109 bool worker_thread::pause(void)
113 if (m_state == WORKER_STATE_PAUSED) {
114 _I("Worker thread is already paused");
118 if (m_state == WORKER_STATE_WORKING) {
119 m_state = WORKER_STATE_PAUSED;
123 _E("Failed to pause, because current state(%d) is not for PAUSE", m_state);
128 bool worker_thread::resume(void)
132 if (m_state == WORKER_STATE_WORKING) {
133 _I("Worker thread is already working");
137 if (m_state == WORKER_STATE_PAUSED) {
138 m_state = WORKER_STATE_WORKING;
139 m_cond_working.notify_one();
143 _E("Failed to resume, because current state(%d) is not for RESUME", m_state);
148 * After state changed to STOPPED, it should not access member fields,
149 because some transition funciton of STOPPED delete this pointer
152 void worker_thread::main(void)
154 _D("Worker thread(%#x) is created", std::this_thread::get_id());
156 transition_function(STARTED);
159 worker_state_t state;
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);
175 if (m_state == WORKER_STATE_PAUSED) {
176 transition_function(PAUSED);
178 _D("Worker thread(%#x) is paused", std::this_thread::get_id());
179 m_cond_working.wait(u);
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);
189 } else if (m_state == WORKER_STATE_STOPPED) {
190 m_thread_created = false;
191 transition_function(STOPPED);
195 _I("Worker thread(%#x)'s main is terminated", std::this_thread::get_id());
198 void worker_thread::set_started(trans_func_t func)
200 m_trans_func[STARTED] = func;
203 void worker_thread::set_stopped(trans_func_t func)
205 m_trans_func[STOPPED] = func;
208 void worker_thread::set_paused(trans_func_t func)
210 m_trans_func[PAUSED] = func;
213 void worker_thread::set_resumed(trans_func_t func)
215 m_trans_func[RESUMED] = func;
218 void worker_thread::set_working(trans_func_t func)
220 m_trans_func[WORKING] = func;
223 void worker_thread::set_context(void *ctx)