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