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 #ifndef _THREAD_HXX_
25 #define _THREAD_HXX_
26
27 #ifdef __cplusplus
28
29 #include <osl/time.h>
30
31
32 #include <osl/diagnose.h>
33 #include <osl/thread.h>
34 #include <rtl/alloc.h>
35
36 namespace osl
37 {
38 /** threadFunc is the function which is executed by the threads
39 created by the osl::Thread class. The function's signature
40 matches the one of oslWorkerFunction which is declared in
41 osl/thread.h .
42 */
43 extern "C" inline void SAL_CALL threadFunc( void* param);
44
45 class Thread
46 {
47 Thread( const Thread& );
48 Thread& operator= ( const Thread& );
49 public:
50 // these are here to force memory de/allocation to sal lib.
operator new(size_t nSize)51 inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW (())
52 { return ::rtl_allocateMemory( nSize ); }
operator delete(void * pMem)53 inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW (())
54 { ::rtl_freeMemory( pMem ); }
operator new(size_t,void * pMem)55 inline static void * SAL_CALL operator new( size_t, void * pMem ) SAL_THROW (())
56 { return pMem; }
operator delete(void *,void *)57 inline static void SAL_CALL operator delete( void *, void * ) SAL_THROW (())
58 {}
59
Thread()60 Thread(): m_hThread(0){}
61
~Thread()62 virtual ~Thread()
63 {
64 osl_destroyThread( m_hThread);
65 }
66
create()67 sal_Bool SAL_CALL create()
68 {
69 OSL_ASSERT(m_hThread == 0); // only one running thread per instance
70 if (m_hThread)
71 return sal_False;
72
73 m_hThread = osl_createSuspendedThread( threadFunc, (void*)this);
74 if ( m_hThread )
75 osl_resumeThread(m_hThread);
76
77 return m_hThread != 0;
78 }
79
createSuspended()80 sal_Bool SAL_CALL createSuspended()
81 {
82 OSL_ASSERT(m_hThread == 0); // only one running thread per instance
83 if( m_hThread)
84 return sal_False;
85 m_hThread= osl_createSuspendedThread( threadFunc,
86 (void*)this);
87 return m_hThread != 0;
88 }
89
suspend()90 virtual void SAL_CALL suspend()
91 {
92 if( m_hThread )
93 osl_suspendThread(m_hThread);
94 }
95
resume()96 virtual void SAL_CALL resume()
97 {
98 if( m_hThread )
99 osl_resumeThread(m_hThread);
100 }
101
terminate()102 virtual void SAL_CALL terminate()
103 {
104 if( m_hThread )
105 osl_terminateThread(m_hThread);
106 }
107
join()108 virtual void SAL_CALL join()
109 {
110 osl_joinWithThread(m_hThread);
111 }
112
isRunning() const113 sal_Bool SAL_CALL isRunning() const
114 {
115 return osl_isThreadRunning(m_hThread);
116 }
117
setPriority(oslThreadPriority Priority)118 void SAL_CALL setPriority( oslThreadPriority Priority)
119 {
120 if( m_hThread )
121 osl_setThreadPriority(m_hThread, Priority);
122 }
123
getPriority() const124 oslThreadPriority SAL_CALL getPriority() const
125 {
126 return m_hThread ? osl_getThreadPriority(m_hThread) : osl_Thread_PriorityUnknown;
127 }
128
getIdentifier() const129 oslThreadIdentifier SAL_CALL getIdentifier() const
130 {
131 return osl_getThreadIdentifier(m_hThread);
132 }
133
getCurrentIdentifier()134 static oslThreadIdentifier SAL_CALL getCurrentIdentifier()
135 {
136 return osl_getThreadIdentifier(0);
137 }
138
wait(const TimeValue & Delay)139 static void SAL_CALL wait(const TimeValue& Delay)
140 {
141 osl_waitThread(&Delay);
142 }
143
yield()144 static void SAL_CALL yield()
145 {
146 osl_yieldThread();
147 }
148
setName(char const * name)149 static inline void setName(char const * name) throw () {
150 osl_setThreadName(name);
151 }
152
schedule()153 virtual sal_Bool SAL_CALL schedule()
154 {
155 return m_hThread ? osl_scheduleThread(m_hThread) : sal_False;
156 }
157
operator oslThread() const158 SAL_CALL operator oslThread() const
159 {
160 return m_hThread;
161 }
162
163 protected:
164
165 /** The thread functions calls the protected functions
166 run and onTerminated.
167 */
168 friend void SAL_CALL threadFunc( void* param);
169
170 virtual void SAL_CALL run() = 0;
171
onTerminated()172 virtual void SAL_CALL onTerminated()
173 {
174 }
175
176 private:
177 oslThread m_hThread;
178 };
179
threadFunc(void * param)180 extern "C" inline void SAL_CALL threadFunc( void* param)
181 {
182 Thread* pObj= (Thread*)param;
183 pObj->run();
184 pObj->onTerminated();
185 }
186
187 class ThreadData
188 {
189 ThreadData( const ThreadData& );
190 ThreadData& operator= (const ThreadData& );
191 public:
192 /// Create a thread specific local data key
ThreadData(oslThreadKeyCallbackFunction pCallback=0)193 ThreadData( oslThreadKeyCallbackFunction pCallback= 0 )
194 {
195 m_hKey = osl_createThreadKey( pCallback );
196 }
197
198 /// Destroy a thread specific local data key
~ThreadData()199 ~ThreadData()
200 {
201 osl_destroyThreadKey(m_hKey);
202 }
203
204 /** Set the data associated with the data key.
205 @returns True if operation was successfull
206 */
setData(void * pData)207 sal_Bool SAL_CALL setData(void *pData)
208 {
209 return (osl_setThreadKeyData(m_hKey, pData));
210 }
211
212 /** Get the data associated with the data key.
213 @returns The data asscoitaed with the data key or
214 NULL if no data was set
215 */
getData()216 void* SAL_CALL getData()
217 {
218 return osl_getThreadKeyData(m_hKey);
219 }
220
operator oslThreadKey() const221 operator oslThreadKey() const
222 {
223 return m_hKey;
224 }
225
226 private:
227 oslThreadKey m_hKey;
228 };
229
230 } // end namespace osl
231 #endif
232 #endif
233