00001 /* 00002 * Copyright (C) 2009, Edmundo Albuquerque de Souza e Silva. 00003 * 00004 * This file may be distributed under the terms of the Q Public License 00005 * as defined by Trolltech AS of Norway and appearing in the file 00006 * LICENSE.QPL included in the packaging of this file. 00007 * 00008 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING 00009 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00010 * PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, 00011 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 00012 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 00013 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 00014 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 00015 * 00016 * Thanks: Jose Renato Santos 00017 * 00018 */ 00019 00020 /////////////////////////////////////////////////////////////////////////////// 00021 // vsithread.cpp: Implementation of VSI thread class: CvsiThread 00022 // 00023 // (VSI: Virtual System Interface) 00024 /////////////////////////////////////////////////////////////////////////////// 00025 00026 #include <vsithread.h> 00027 #include <vsierror.h> 00028 00029 // For SIGKILL 00030 #include <signal.h> 00031 00032 const int THREAD_INACTIVE = 0; 00033 const int THREAD_ACTIVE = 1; 00034 00035 /////////////////////////////////////////////////////////////////////////////// 00036 // Construction/Destruction 00037 /////////////////////////////////////////////////////////////////////////////// 00038 00039 CvsiThread::CvsiThread() 00040 { 00041 m_Thread = 0; 00042 m_Stat = THREAD_INACTIVE; 00043 pthread_attr_init( &m_Attr ); 00044 pthread_attr_setstacksize( &m_Attr, 2*PTHREAD_STACK_MIN ); 00045 m_UserRoutine = NULL; 00046 m_Arg = NULL; 00047 } 00048 00049 CvsiThread::~CvsiThread() 00050 { 00051 00052 } 00053 00054 /////////////////////////////////////////////////////////////////////////////// 00055 // Check is thread is running 00056 int CvsiThread::IsActive() 00057 { 00058 if(m_Stat == THREAD_ACTIVE) 00059 return true; 00060 else 00061 return false; 00062 } 00063 /////////////////////////////////////////////////////////////////////////////// 00064 // Thread start routine: Wraps the user defined routine 00065 void* CvsiThread::Thread(void* Arg) 00066 { 00067 CvsiThread* t = (CvsiThread*) Arg; 00068 void* Result = t->m_UserRoutine(t->m_Arg); 00069 // t->m_Stat = THREAD_INACTIVE; 00070 t->m_UserRoutine = NULL; 00071 pthread_exit( Result ); 00072 } 00073 00074 /////////////////////////////////////////////////////////////////////////////// 00075 // Create thread 00076 int CvsiThread::Create(void* (*StartRoutine)(void*), void* Arg) 00077 { 00078 // Check if thread not running 00079 if(m_Stat == THREAD_ACTIVE) 00080 { 00081 return VSI_ERROR_THREAD_ACTIVE; 00082 } 00083 00084 m_Stat = THREAD_ACTIVE; 00085 00086 m_UserRoutine = StartRoutine; 00087 m_Arg = Arg; 00088 00089 if(pthread_create (&m_Thread, &m_Attr, &Thread, (void*) this) != 0) 00090 { 00091 m_Stat = THREAD_INACTIVE; 00092 return VSI_ERROR_THREAD_CREATE; 00093 } 00094 00095 return 0; 00096 } 00097 00098 /////////////////////////////////////////////////////////////////////////////// 00099 // Join Thread (i.e. wait thread termination) 00100 int CvsiThread::Join(void **Result) 00101 { 00102 if(m_Stat == THREAD_INACTIVE) 00103 return VSI_ERROR_THREAD_INACTIVE; 00104 00105 00106 if( pthread_join (m_Thread, Result) != 0) 00107 return VSI_ERROR_THREAD_JOIN; 00108 00109 m_Stat = THREAD_INACTIVE; 00110 00111 return 0; 00112 } 00113 00114 /////////////////////////////////////////////////////////////////////////////// 00115 // Set Thread scope: System or Process 00116 int CvsiThread::SetScope(int Scope) 00117 { 00118 // Check if thread not running 00119 if(m_Stat == THREAD_ACTIVE) 00120 return VSI_ERROR_THREAD_ACTIVE; 00121 00122 int sc; 00123 00124 if(Scope == VSI_THREAD_SCOPE_SYSTEM) 00125 sc = PTHREAD_SCOPE_SYSTEM; 00126 else if(Scope == VSI_THREAD_SCOPE_PROCESS) 00127 sc = PTHREAD_SCOPE_PROCESS; 00128 else 00129 return VSI_ERROR_INVALID_PARAMETER; 00130 00131 if(pthread_attr_setscope (&m_Attr,sc) != 0) 00132 return VSI_ERROR_THREAD_SETSCOPE; 00133 00134 return 0; 00135 }