xref: /AOO41X/main/vos/source/thread.cxx (revision e8c8fa4bdcac50a8fe6c60960dd164b285c48c7e)
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