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