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
threadWorkerFunction_impl(void * pthis)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
OThread()56 OThread::OThread()
57 {
58 m_hThread = 0;
59 m_bTerminating = sal_False;
60 m_aCondition = osl_createCondition();
61 }
62
~OThread()63 OThread::~OThread()
64 {
65 if (m_hThread != 0)
66 {
67 osl_destroyThread(m_hThread);
68 }
69
70 osl_destroyCondition( m_aCondition );
71 }
72
create()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
createSuspended()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
suspend()93 void OThread::suspend()
94 {
95 VOS_ASSERT(m_hThread != 0); // use only on running thread
96
97 osl_suspendThread(m_hThread);
98 }
99
resume()100 void OThread::resume()
101 {
102 VOS_ASSERT(m_hThread != 0); // use only on running thread
103
104 osl_resumeThread(m_hThread);
105 }
106
isRunning()107 sal_Bool OThread::isRunning()
108 {
109 return m_hThread != 0 && osl_isThreadRunning(m_hThread);
110 }
111
getIdentifier() const112 OThread::TThreadIdentifier OThread::getIdentifier() const
113 {
114 return (TThreadIdentifier)osl_getThreadIdentifier(m_hThread);
115 }
116
getCurrentIdentifier()117 OThread::TThreadIdentifier OThread::getCurrentIdentifier()
118 {
119 return (TThreadIdentifier)osl_getThreadIdentifier(0);
120 }
121
join()122 void OThread::join()
123 {
124 if (m_hThread) {
125 VOS_ASSERT(getCurrentIdentifier() != getIdentifier());
126 osl_joinWithThread(m_hThread);
127 }
128 }
129
sleep(const TimeValue & Delay)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
wait(const TimeValue & Delay)152 void OThread::wait(const TimeValue& Delay) {
153 osl_waitThread(&Delay);
154 }
155
awake()156 sal_Bool OThread::awake()
157 {
158 osl_setCondition( m_aCondition );
159 return osl_resetCondition( m_aCondition );
160 }
161
terminate()162 void OThread::terminate()
163 {
164 osl_terminateThread(m_hThread);
165 }
166
schedule()167 sal_Bool OThread::schedule() {
168 return osl_scheduleThread(m_hThread);
169 }
170
kill()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
setPriority(OThread::TThreadPriority Priority)183 void OThread::setPriority(OThread::TThreadPriority Priority)
184 {
185 osl_setThreadPriority(m_hThread, (oslThreadPriority)Priority);
186 }
187
getPriority()188 OThread::TThreadPriority OThread::getPriority()
189 {
190 return (TThreadPriority)osl_getThreadPriority(m_hThread);
191 }
192
193
yield()194 void OThread::yield()
195 {
196 osl_yieldThread();
197 }
198
onTerminated()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
OThreadData(oslThreadKeyCallbackFunction pCallback)212 OThreadData::OThreadData( oslThreadKeyCallbackFunction pCallback )
213 {
214 m_hKey = osl_createThreadKey( pCallback );
215 VOS_VERIFY(m_hKey);
216 }
217
~OThreadData()218 OThreadData::~OThreadData()
219 {
220 osl_destroyThreadKey(m_hKey);
221 }
222
setData(void * pData)223 sal_Bool OThreadData::setData(void *pData)
224 {
225 VOS_ASSERT(m_hKey != 0);
226
227 return (osl_setThreadKeyData(m_hKey, pData));
228 }
229
getData()230 void *OThreadData::getData()
231 {
232 VOS_ASSERT(m_hKey != 0);
233
234 return (osl_getThreadKeyData(m_hKey));
235 }
236
237