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 (at) intel.com> 19 */ 20 21 #include "xcam_thread.h" 22 #include "xcam_mutex.h" 23 #include <errno.h> 24 25 namespace XCam { 26 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 37 Thread::~Thread () 38 { 39 if (_name) 40 xcam_free (_name); 41 } 42 43 int 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 80 Thread::started () 81 { 82 XCAM_LOG_DEBUG ("Thread(%s) started", XCAM_STR(_name)); 83 return true; 84 } 85 86 void 87 Thread::stopped () 88 { 89 XCAM_LOG_DEBUG ("Thread(%s) stopped", XCAM_STR(_name)); 90 } 91 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 117 Thread::emit_stop () 118 { 119 SmartLock locker(_mutex); 120 _started = false; 121 return true; 122 } 123 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 136 bool Thread::is_running () 137 { 138 SmartLock locker(_mutex); 139 return _started; 140 } 141 142 }; 143