1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include <osl/time.h> 25 #include <vos/diagnose.hxx> 26 #include <vos/object.hxx> 27 #include <vos/thread.hxx> 28 29 using namespace vos; 30 31 void vos::threadWorkerFunction_impl(void * pthis) 32 { 33 vos::OThread* pThis= (vos::OThread*)pthis; 34 35 // call Handler-Function of OThread-derived class 36 pThis->run(); 37 38 // if not already terminating, by a kill do normal shutdown 39 if (! pThis->m_bTerminating) 40 { 41 pThis->m_bTerminating = sal_True; 42 43 pThis->onTerminated(); // could e.g. delete this 44 } 45 } 46 47 ///////////////////////////////////////////////////////////////////////////// 48 // 49 // Thread class 50 // 51 52 VOS_IMPLEMENT_CLASSINFO(VOS_CLASSNAME(OThread, vos), 53 VOS_NAMESPACE(OThread, vos), 54 VOS_NAMESPACE(OObject, vos), 0); 55 56 OThread::OThread() 57 { 58 m_hThread = 0; 59 m_bTerminating = sal_False; 60 m_aCondition = osl_createCondition(); 61 } 62 63 OThread::~OThread() 64 { 65 if (m_hThread != 0) 66 { 67 osl_destroyThread(m_hThread); 68 } 69 70 osl_destroyCondition( m_aCondition ); 71 } 72 73 sal_Bool OThread::create() 74 { 75 VOS_ASSERT(m_hThread == 0); // only one running thread per instance 76 77 m_hThread = osl_createSuspendedThread( 78 threadWorkerFunction_impl, (void*)this); 79 if (m_hThread) 80 osl_resumeThread(m_hThread); 81 82 return m_hThread != 0; 83 } 84 85 sal_Bool OThread::createSuspended() 86 { 87 VOS_ASSERT(m_hThread == 0); // only one running thread per instance 88 89 m_hThread= osl_createSuspendedThread(threadWorkerFunction_impl, (void*)this); 90 return m_hThread != 0; 91 } 92 93 void OThread::suspend() 94 { 95 VOS_ASSERT(m_hThread != 0); // use only on running thread 96 97 osl_suspendThread(m_hThread); 98 } 99 100 void OThread::resume() 101 { 102 VOS_ASSERT(m_hThread != 0); // use only on running thread 103 104 osl_resumeThread(m_hThread); 105 } 106 107 sal_Bool OThread::isRunning() 108 { 109 return m_hThread != 0 && osl_isThreadRunning(m_hThread); 110 } 111 112 OThread::TThreadIdentifier OThread::getIdentifier() const 113 { 114 return (TThreadIdentifier)osl_getThreadIdentifier(m_hThread); 115 } 116 117 OThread::TThreadIdentifier OThread::getCurrentIdentifier() 118 { 119 return (TThreadIdentifier)osl_getThreadIdentifier(0); 120 } 121 122 void OThread::join() 123 { 124 if (m_hThread) { 125 VOS_ASSERT(getCurrentIdentifier() != getIdentifier()); 126 osl_joinWithThread(m_hThread); 127 } 128 } 129 130 OThread::TThreadSleep OThread::sleep(const TimeValue& Delay) 131 { 132 TThreadSleep eRet; 133 134 switch( osl_waitCondition( m_aCondition, &Delay ) ) 135 { 136 case osl_cond_result_ok: 137 eRet = TSleep_Normal; 138 break; 139 140 case osl_cond_result_timeout: 141 eRet = TSleep_Cancel; 142 break; 143 144 default: 145 eRet = TSleep_Error; 146 break; 147 } 148 149 return eRet; 150 } 151 152 void OThread::wait(const TimeValue& Delay) { 153 osl_waitThread(&Delay); 154 } 155 156 sal_Bool OThread::awake() 157 { 158 osl_setCondition( m_aCondition ); 159 return osl_resetCondition( m_aCondition ); 160 } 161 162 void OThread::terminate() 163 { 164 osl_terminateThread(m_hThread); 165 } 166 167 sal_Bool OThread::schedule() { 168 return osl_scheduleThread(m_hThread); 169 } 170 171 void OThread::kill() 172 { 173 if (osl_isThreadRunning(m_hThread)) 174 { 175 // flag we are shutting down 176 m_bTerminating = sal_True; 177 178 terminate(); 179 join(); 180 } 181 } 182 183 void OThread::setPriority(OThread::TThreadPriority Priority) 184 { 185 osl_setThreadPriority(m_hThread, (oslThreadPriority)Priority); 186 } 187 188 OThread::TThreadPriority OThread::getPriority() 189 { 190 return (TThreadPriority)osl_getThreadPriority(m_hThread); 191 } 192 193 194 void OThread::yield() 195 { 196 osl_yieldThread(); 197 } 198 199 void OThread::onTerminated() 200 { 201 } 202 203 ///////////////////////////////////////////////////////////////////////////// 204 // 205 // ThreadData class 206 // 207 208 VOS_IMPLEMENT_CLASSINFO(VOS_CLASSNAME(OThreadData, vos), 209 VOS_NAMESPACE(OThreadData, vos), 210 VOS_NAMESPACE(OObject, vos), 0); 211 212 OThreadData::OThreadData( oslThreadKeyCallbackFunction pCallback ) 213 { 214 m_hKey = osl_createThreadKey( pCallback ); 215 VOS_VERIFY(m_hKey); 216 } 217 218 OThreadData::~OThreadData() 219 { 220 osl_destroyThreadKey(m_hKey); 221 } 222 223 sal_Bool OThreadData::setData(void *pData) 224 { 225 VOS_ASSERT(m_hKey != 0); 226 227 return (osl_setThreadKeyData(m_hKey, pData)); 228 } 229 230 void *OThreadData::getData() 231 { 232 VOS_ASSERT(m_hKey != 0); 233 234 return (osl_getThreadKeyData(m_hKey)); 235 } 236 237