00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 00002 /* 00003 * This file is part of the LibreOffice project. 00004 * 00005 * This Source Code Form is subject to the terms of the Mozilla Public 00006 * License, v. 2.0. If a copy of the MPL was not distributed with this 00007 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 00008 * 00009 * This file incorporates work covered by the following license notice: 00010 * 00011 * Licensed to the Apache Software Foundation (ASF) under one or more 00012 * contributor license agreements. See the NOTICE file distributed 00013 * with this work for additional information regarding copyright 00014 * ownership. The ASF licenses this file to you under the Apache 00015 * License, Version 2.0 (the "License"); you may not use this file 00016 * except in compliance with the License. You may obtain a copy of 00017 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 00018 */ 00019 00020 #ifndef _THREAD_HXX_ 00021 #define _THREAD_HXX_ 00022 00023 #include "sal/config.h" 00024 00025 #include <cassert> 00026 00027 #include <osl/time.h> 00028 00029 00030 #include <osl/diagnose.h> 00031 #include <osl/thread.h> 00032 #include <rtl/alloc.h> 00033 00034 namespace osl 00035 { 00041 extern "C" inline void SAL_CALL threadFunc( void* param); 00042 00050 class Thread 00051 { 00052 Thread( const Thread& ); 00053 Thread& operator= ( const Thread& ); 00054 public: 00055 // these are here to force memory de/allocation to sal lib. 00056 inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW (()) 00057 { return ::rtl_allocateMemory( nSize ); } 00058 inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW (()) 00059 { ::rtl_freeMemory( pMem ); } 00060 inline static void * SAL_CALL operator new( size_t, void * pMem ) SAL_THROW (()) 00061 { return pMem; } 00062 inline static void SAL_CALL operator delete( void *, void * ) SAL_THROW (()) 00063 {} 00064 00065 Thread(): m_hThread(0){} 00066 00067 virtual ~Thread() 00068 { 00069 osl_destroyThread( m_hThread); 00070 } 00071 00072 sal_Bool SAL_CALL create() 00073 { 00074 assert(m_hThread == 0); // only one running thread per instance 00075 m_hThread = osl_createSuspendedThread( threadFunc, (void*)this); 00076 if (m_hThread == 0) 00077 { 00078 return false; 00079 } 00080 osl_resumeThread(m_hThread); 00081 return true; 00082 } 00083 00084 sal_Bool SAL_CALL createSuspended() 00085 { 00086 assert(m_hThread == 0); // only one running thread per instance 00087 if( m_hThread) 00088 return sal_False; 00089 m_hThread= osl_createSuspendedThread( threadFunc, 00090 (void*)this); 00091 return m_hThread != 0; 00092 } 00093 00094 virtual void SAL_CALL suspend() 00095 { 00096 if( m_hThread ) 00097 osl_suspendThread(m_hThread); 00098 } 00099 00100 virtual void SAL_CALL resume() 00101 { 00102 if( m_hThread ) 00103 osl_resumeThread(m_hThread); 00104 } 00105 00106 virtual void SAL_CALL terminate() 00107 { 00108 if( m_hThread ) 00109 osl_terminateThread(m_hThread); 00110 } 00111 00112 virtual void SAL_CALL join() 00113 { 00114 osl_joinWithThread(m_hThread); 00115 } 00116 00117 sal_Bool SAL_CALL isRunning() const 00118 { 00119 return osl_isThreadRunning(m_hThread); 00120 } 00121 00122 void SAL_CALL setPriority( oslThreadPriority Priority) 00123 { 00124 if( m_hThread ) 00125 osl_setThreadPriority(m_hThread, Priority); 00126 } 00127 00128 oslThreadPriority SAL_CALL getPriority() const 00129 { 00130 return m_hThread ? osl_getThreadPriority(m_hThread) : osl_Thread_PriorityUnknown; 00131 } 00132 00133 oslThreadIdentifier SAL_CALL getIdentifier() const 00134 { 00135 return osl_getThreadIdentifier(m_hThread); 00136 } 00137 00138 static oslThreadIdentifier SAL_CALL getCurrentIdentifier() 00139 { 00140 return osl_getThreadIdentifier(0); 00141 } 00142 00143 static void SAL_CALL wait(const TimeValue& Delay) 00144 { 00145 osl_waitThread(&Delay); 00146 } 00147 00148 static void SAL_CALL yield() 00149 { 00150 osl_yieldThread(); 00151 } 00152 00153 static inline void setName(char const * name) throw () { 00154 osl_setThreadName(name); 00155 } 00156 00157 virtual sal_Bool SAL_CALL schedule() 00158 { 00159 return m_hThread ? osl_scheduleThread(m_hThread) : sal_False; 00160 } 00161 00162 SAL_CALL operator oslThread() const 00163 { 00164 return m_hThread; 00165 } 00166 00167 protected: 00168 00172 friend void SAL_CALL threadFunc( void* param); 00173 00174 virtual void SAL_CALL run() = 0; 00175 00176 virtual void SAL_CALL onTerminated() 00177 { 00178 } 00179 00180 private: 00181 oslThread m_hThread; 00182 }; 00183 00184 extern "C" inline void SAL_CALL threadFunc( void* param) 00185 { 00186 Thread* pObj= (Thread*)param; 00187 pObj->run(); 00188 pObj->onTerminated(); 00189 } 00190 00191 class ThreadData 00192 { 00193 ThreadData( const ThreadData& ); 00194 ThreadData& operator= (const ThreadData& ); 00195 public: 00197 ThreadData( oslThreadKeyCallbackFunction pCallback= 0 ) 00198 { 00199 m_hKey = osl_createThreadKey( pCallback ); 00200 } 00201 00203 ~ThreadData() 00204 { 00205 osl_destroyThreadKey(m_hKey); 00206 } 00207 00211 sal_Bool SAL_CALL setData(void *pData) 00212 { 00213 return (osl_setThreadKeyData(m_hKey, pData)); 00214 } 00215 00220 void* SAL_CALL getData() 00221 { 00222 return osl_getThreadKeyData(m_hKey); 00223 } 00224 00225 operator oslThreadKey() const 00226 { 00227 return m_hKey; 00228 } 00229 00230 private: 00231 oslThreadKey m_hKey; 00232 }; 00233 00234 } // end namespace osl 00235 00236 #endif 00237 00238 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */