81e0c7822b7c38609d08403354dd865b97301940
[platform/core/system/libsf-common.git] / src / cworker.cpp
1 /*
2  *  libsf-common
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: JuHyun Kim <jh8212.kim@samsung.com>
7  * 
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */ 
21
22
23
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <pthread.h>
29 #include <errno.h>
30 #include <sys/wait.h>
31 #include <unistd.h>
32 #include <signal.h>
33 #include <cobject_type.h>
34 #include <csync.h>
35 #include <clist.h>
36 #include <cmutex.h>
37 #include <cworker.h>
38 #include <common.h>
39
40         cworker::cworker(void)
41         : m_state(INITIAL)
42         , m_context(NULL)
43         , mutex_lock(PTHREAD_MUTEX_INITIALIZER)
44           , th_cond(PTHREAD_COND_INITIALIZER)
45 {
46         register int i;
47         int ret;
48         for (i = 0; i < ENUM_LAST; i ++) {
49                 m_func[i] = NULL;
50         }
51
52         ret = pthread_mutex_init(&mutex_lock, NULL);
53         if (ret != 0) {
54                 ERR("pthread_mutex_init : %s",strerror(errno));
55                 throw EINVAL;
56         }
57
58         ret = pthread_cond_init(&th_cond, NULL);
59         if (ret != 0) {
60                 ERR("pthread_cond_init : %s",strerror(errno));
61                 throw EINVAL;
62         }
63         DBG("processor worker created\n");
64 }
65
66 cworker::~cworker(void)
67 {
68         DBG("----------Processor WORKER TERMINATED--------\n"); 
69
70         pthread_mutex_lock(&(mutex_lock));
71
72         m_state = TERMINATE;
73         pthread_cond_signal(&th_cond);
74
75         pthread_mutex_unlock(&(mutex_lock));
76
77         pthread_cond_destroy(&th_cond);
78
79         if (m_func[TERMINATE])
80                 m_func[TERMINATE](m_context);
81
82         DBG("processor worker terminated\n");
83 }
84
85 bool cworker::start(void)
86 {
87         int ret = 0;
88
89         pthread_mutex_lock(&(mutex_lock));
90
91         if(m_state == INITIAL)
92         {
93                 pthread_mutex_unlock(&(mutex_lock));
94                 ret = pthread_create(&m_thid, NULL, started, this);
95
96                 if(ret != 0)
97                 {
98                         pthread_mutex_lock(&(mutex_lock));
99                         m_state = INITIAL;
100                         pthread_mutex_unlock(&(mutex_lock));
101                         ERR("thread create fail\n");
102                         return false;
103                 }
104                 else
105                 {
106                         pthread_detach(m_thid);
107                 }
108
109                 pthread_mutex_lock(&(mutex_lock));
110         }
111         else if (m_state == START) {
112                 ERR("Already started\n");
113                 pthread_mutex_unlock(&(mutex_lock));
114                 return false;
115         }
116
117         ret = pthread_cond_signal(&th_cond);
118         if (ret != 0) {
119                 ERR("pthread_cond_wait : %s",strerror(errno));
120         }
121
122         m_state = START;
123         pthread_mutex_unlock(&(mutex_lock));
124
125         return true;
126 }
127
128 bool cworker::terminate(void)
129 {
130         pthread_mutex_lock(&(mutex_lock));
131         m_state = TERMINATE;
132         pthread_mutex_unlock(&(mutex_lock));
133         delete this;
134         return true;
135 }
136
137 void *cworker::started(void *data)
138 {
139         cworker *inst = (cworker*)data;
140         worker_state_s state = STOPPED;
141
142         do
143         {
144                 state = (worker_state_s)(int)inst->m_func[STARTED](inst->m_context);
145
146                 if(state == STOPPED || inst->m_state == STOP)
147                         inst->stopped();
148
149         }while(state != TERMINATE);
150
151         return NULL;            
152 }
153
154 bool cworker::stop(void)
155 {
156         pthread_mutex_lock(&(mutex_lock));
157         if (m_state == STOP) {
158                 ERR("Already stopped\n");
159                 pthread_mutex_unlock(&(mutex_lock));
160                 return false;
161         }
162         m_state = STOP;
163         pthread_mutex_unlock(&(mutex_lock));
164
165         return true;
166 }
167
168 bool cworker::stopped(void)
169 {
170         pthread_mutex_lock(&mutex_lock);
171         pthread_cond_wait(&th_cond, &mutex_lock);
172         pthread_mutex_unlock(&mutex_lock);
173         return true;
174 }
175
176 cworker::worker_state_s cworker::state(void)
177 {
178         return m_state;
179 }
180
181 void cworker::set_start(void *(*start)(void *data))
182 {
183         m_func[START] = start;
184 }
185
186 void cworker::set_started(void *(*started)(void *data))
187 {
188         m_func[STARTED] = started;
189 }
190
191 void cworker::set_stop(void *(*stop)(void *data))
192 {
193         m_func[STOP] = stop;
194 }
195
196 void cworker::set_stopped(void *(*stopped)(void *data))
197 {
198         m_func[STOPPED] = stopped;
199 }
200
201 void cworker::set_terminate(void *(*term)(void *data))
202 {
203         m_func[TERMINATE] = term;
204 }
205
206 void cworker::set_context(void *ctx)
207 {
208         m_context = ctx;
209 }
210
211 //! End of a file