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