1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include <osl/time.h> 29 #include <vos/diagnose.hxx> 30 #include <vos/object.hxx> 31 #include <vos/thread.hxx> 32 33 using namespace vos; 34 35 void vos::threadWorkerFunction_impl(void * pthis) 36 { 37 vos::OThread* pThis= (vos::OThread*)pthis; 38 39 // call Handler-Function of OThread-derived class 40 pThis->run(); 41 42 // if not already terminating, by a kill do normal shutdown 43 if (! pThis->m_bTerminating) 44 { 45 pThis->m_bTerminating = sal_True; 46 47 pThis->onTerminated(); // could e.g. delete this 48 } 49 } 50 51 ///////////////////////////////////////////////////////////////////////////// 52 // 53 // Thread class 54 // 55 56 VOS_IMPLEMENT_CLASSINFO(VOS_CLASSNAME(OThread, vos), 57 VOS_NAMESPACE(OThread, vos), 58 VOS_NAMESPACE(OObject, vos), 0); 59 60 OThread::OThread() 61 { 62 m_hThread = 0; 63 m_bTerminating = sal_False; 64 m_aCondition = osl_createCondition(); 65 } 66 67 OThread::~OThread() 68 { 69 if (m_hThread != 0) 70 { 71 osl_destroyThread(m_hThread); 72 } 73 74 osl_destroyCondition( m_aCondition ); 75 } 76 77 sal_Bool OThread::create() 78 { 79 VOS_ASSERT(m_hThread == 0); // only one running thread per instance 80 81 m_hThread = osl_createSuspendedThread( 82 threadWorkerFunction_impl, (void*)this); 83 if (m_hThread) 84 osl_resumeThread(m_hThread); 85 86 return m_hThread != 0; 87 } 88 89 sal_Bool OThread::createSuspended() 90 { 91 VOS_ASSERT(m_hThread == 0); // only one running thread per instance 92 93 m_hThread= osl_createSuspendedThread(threadWorkerFunction_impl, (void*)this); 94 return m_hThread != 0; 95 } 96 97 void OThread::suspend() 98 { 99 VOS_ASSERT(m_hThread != 0); // use only on running thread 100 101 osl_suspendThread(m_hThread); 102 } 103 104 void OThread::resume() 105 { 106 VOS_ASSERT(m_hThread != 0); // use only on running thread 107 108 osl_resumeThread(m_hThread); 109 } 110 111 sal_Bool OThread::isRunning() 112 { 113 return m_hThread != 0 && osl_isThreadRunning(m_hThread); 114 } 115 116 OThread::TThreadIdentifier OThread::getIdentifier() const 117 { 118 return (TThreadIdentifier)osl_getThreadIdentifier(m_hThread); 119 } 120 121 OThread::TThreadIdentifier OThread::getCurrentIdentifier() 122 { 123 return (TThreadIdentifier)osl_getThreadIdentifier(0); 124 } 125 126 void OThread::join() 127 { 128 if (m_hThread) { 129 VOS_ASSERT(getCurrentIdentifier() != getIdentifier()); 130 osl_joinWithThread(m_hThread); 131 } 132 } 133 134 OThread::TThreadSleep OThread::sleep(const TimeValue& Delay) 135 { 136 TThreadSleep eRet; 137 138 switch( osl_waitCondition( m_aCondition, &Delay ) ) 139 { 140 case osl_cond_result_ok: 141 eRet = TSleep_Normal; 142 break; 143 144 case osl_cond_result_timeout: 145 eRet = TSleep_Cancel; 146 break; 147 148 default: 149 eRet = TSleep_Error; 150 break; 151 } 152 153 return eRet; 154 } 155 156 void OThread::wait(const TimeValue& Delay) { 157 osl_waitThread(&Delay); 158 } 159 160 sal_Bool OThread::awake() 161 { 162 osl_setCondition( m_aCondition ); 163 return osl_resetCondition( m_aCondition ); 164 } 165 166 void OThread::terminate() 167 { 168 osl_terminateThread(m_hThread); 169 } 170 171 sal_Bool OThread::schedule() { 172 return osl_scheduleThread(m_hThread); 173 } 174 175 void OThread::kill() 176 { 177 if (osl_isThreadRunning(m_hThread)) 178 { 179 // flag we are shutting down 180 m_bTerminating = sal_True; 181 182 terminate(); 183 join(); 184 } 185 } 186 187 void OThread::setPriority(OThread::TThreadPriority Priority) 188 { 189 osl_setThreadPriority(m_hThread, (oslThreadPriority)Priority); 190 } 191 192 OThread::TThreadPriority OThread::getPriority() 193 { 194 return (TThreadPriority)osl_getThreadPriority(m_hThread); 195 } 196 197 198 void OThread::yield() 199 { 200 osl_yieldThread(); 201 } 202 203 void OThread::onTerminated() 204 { 205 } 206 207 ///////////////////////////////////////////////////////////////////////////// 208 // 209 // ThreadData class 210 // 211 212 VOS_IMPLEMENT_CLASSINFO(VOS_CLASSNAME(OThreadData, vos), 213 VOS_NAMESPACE(OThreadData, vos), 214 VOS_NAMESPACE(OObject, vos), 0); 215 216 OThreadData::OThreadData( oslThreadKeyCallbackFunction pCallback ) 217 { 218 m_hKey = osl_createThreadKey( pCallback ); 219 VOS_VERIFY(m_hKey); 220 } 221 222 OThreadData::~OThreadData() 223 { 224 osl_destroyThreadKey(m_hKey); 225 } 226 227 sal_Bool OThreadData::setData(void *pData) 228 { 229 VOS_ASSERT(m_hKey != 0); 230 231 return (osl_setThreadKeyData(m_hKey, pData)); 232 } 233 234 void *OThreadData::getData() 235 { 236 VOS_ASSERT(m_hKey != 0); 237 238 return (osl_getThreadKeyData(m_hKey)); 239 } 240 241