1 /*
2  * xcam_thread.cpp - Thread
3  *
4  *  Copyright (c) 2014 Intel Corporation
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  * Author: Wind Yuan <feng.yuan@intel.com>
19  */
20 
21 #include "xcam_thread.h"
22 #include "xcam_mutex.h"
23 #include <errno.h>
24 
25 namespace XCam {
26 
Thread(const char * name)27 Thread::Thread (const char *name)
28     : _name (NULL)
29     , _thread_id (0)
30     , _started (false)
31     , _stopped (true)
32 {
33     if (name)
34         _name = strndup (name, XCAM_MAX_STR_SIZE);
35 }
36 
~Thread()37 Thread::~Thread ()
38 {
39     if (_name)
40         xcam_free (_name);
41 }
42 
43 int
thread_func(void * user_data)44 Thread::thread_func (void *user_data)
45 {
46     Thread *thread = (Thread *)user_data;
47     bool ret = true;
48 
49     {
50         // Make sure running after start
51         SmartLock locker(thread->_mutex);
52         pthread_detach (pthread_self());
53     }
54     ret = thread->started ();
55 
56     while (true) {
57         {
58             SmartLock locker(thread->_mutex);
59             if (!thread->_started || ret == false) {
60                 thread->_started = false;
61                 thread->_thread_id = 0;
62                 ret = false;
63                 break;
64             }
65         }
66 
67         ret = thread->loop ();
68     }
69 
70     thread->stopped ();
71 
72     SmartLock locker(thread->_mutex);
73     thread->_stopped = true;
74     thread->_exit_cond.broadcast ();
75 
76     return 0;
77 }
78 
79 bool
started()80 Thread::started ()
81 {
82     XCAM_LOG_DEBUG ("Thread(%s) started", XCAM_STR(_name));
83     return true;
84 }
85 
86 void
stopped()87 Thread::stopped ()
88 {
89     XCAM_LOG_DEBUG ("Thread(%s) stopped", XCAM_STR(_name));
90 }
91 
start()92 bool Thread::start ()
93 {
94     SmartLock locker(_mutex);
95     if (_started)
96         return true;
97 
98     if (pthread_create (&_thread_id, NULL, (void * (*)(void*))thread_func, this) != 0)
99         return false;
100     _started = true;
101     _stopped = false;
102 
103 #ifdef __USE_GNU
104     char thread_name[16];
105     xcam_mem_clear (thread_name);
106     snprintf (thread_name, sizeof (thread_name), "xc:%s", XCAM_STR(_name));
107     int ret = pthread_setname_np (_thread_id, thread_name);
108     if (ret != 0) {
109         XCAM_LOG_WARNING ("Thread(%s) set name to thread_id failed.(%d, %s)", XCAM_STR(_name), ret, strerror(ret));
110     }
111 #endif
112 
113     return true;
114 }
115 
116 bool
emit_stop()117 Thread::emit_stop ()
118 {
119     SmartLock locker(_mutex);
120     _started = false;
121     return true;
122 }
123 
stop()124 bool Thread::stop ()
125 {
126     SmartLock locker(_mutex);
127     if (_started) {
128         _started = false;
129     }
130     if (!_stopped) {
131         _exit_cond.wait(_mutex);
132     }
133     return true;
134 }
135 
is_running()136 bool Thread::is_running ()
137 {
138     SmartLock locker(_mutex);
139     return _started;
140 }
141 
142 };
143