xref: /trunk/main/vos/inc/vos/thread.hxx (revision 914d351e5f5b84e4342a86d6ab8d4aca7308b9bd)
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 _VOS_THREAD_HXX_
25 #define _VOS_THREAD_HXX_
26 
27 #   include <vos/types.hxx>
28 #   include <vos/object.hxx>
29 #   include <osl/thread.h>
30 #   include <osl/conditn.h>
31 #   include <vos/runnable.hxx>
32 #   include <vos/vosdllapi.h>
33 
34 #include <osl/time.h>
35 
36 namespace vos
37 {
38 
39 extern "C" typedef void ThreadWorkerFunction_impl(void *);
40 ThreadWorkerFunction_impl threadWorkerFunction_impl;
41 
42 /** OThread is an object oriented interface for threads.
43     This class should be the base class for all objects using threads. The
44     main working function is the run() method and should be overridden in the
45     derived class. To support soft termination of a thread, yield() should
46     be called in regular intervals and the return value should be checked.
47     If yield returned False the run method should return.
48 
49     @author  Bernd Hofner
50     @version 1.0
51 */
52 
53 class VOS_DLLPUBLIC OThread : public vos::IRunnable,
54                 public vos::OObject
55 {
56 
57     VOS_DECLARE_CLASSINFO(VOS_NAMESPACE(OThread, vos));
58 
59     oslCondition m_aCondition;
60 
61 public:
62     /** priority of thread.
63     */
64     enum TThreadPriority
65     {
66         TPriority_Highest     = osl_Thread_PriorityHighest,
67         TPriority_AboveNormal = osl_Thread_PriorityAboveNormal,
68         TPriority_Normal      = osl_Thread_PriorityNormal,
69         TPriority_BelowNormal = osl_Thread_PriorityBelowNormal,
70         TPriority_Lowest      = osl_Thread_PriorityLowest,
71         TPriority_Unknown     = osl_Thread_PriorityUnknown
72     };
73 
74     /**
75     */
76     enum TThreadSleep
77     {
78         TSleep_Normal,
79         TSleep_Cancel,
80         TSleep_Pending,
81         TSleep_Active,
82         TSleep_Error,
83         TSleep_Unknown
84     };
85 
86     typedef oslThreadIdentifier TThreadIdentifier;
87 
88     /// Constructor
89     OThread();
90 
91     /// Destructor kills thread if necessary
92     virtual ~OThread();
93 
94     /** Create running instance of a thread.
95         @returns True if thread could be created.
96     */
97     sal_Bool SAL_CALL create();
98 
99     /** Create suspended instance of a thread.
100         @returns True if thread could be created.
101     */
102     sal_Bool SAL_CALL createSuspended();
103 
104     /// Suspend a running thread
105     void SAL_CALL suspend();
106 
107     /// Resume a suspended thread
108     void SAL_CALL resume();
109 
110     /** Tries to kill the thread.
111         will not block and might not succeed when run() won't heed isTerminationRequested().
112     */
113     virtual void SAL_CALL terminate();
114 
115     /// Kill thread hard and block until it is actually gone
116     virtual void SAL_CALL kill();
117 
118     /// Block till thread is terminated
119     void SAL_CALL join();
120 
121     /// Check if thread is running.
122     sal_Bool SAL_CALL isRunning();
123 
124     /** Change thread priority.
125         The valid priority levels are:
126     <ul>
127         <li>ThreadPriorityHighest,
128         <li>ThreadPriorityAboveNormal,
129         <li>ThreadPriorityNormal,
130         <li>ThreadPriorityBelowNormal,
131         <li>ThreadPriorityLowest,
132     </ul>
133     */
134     void SAL_CALL setPriority(TThreadPriority Priority);
135 
136     /** Query thread priority.
137         Valid return values are:
138     <ul>
139         <li>ThreadPriorityHighest,
140         <li>ThreadPriorityAboveNormal,
141         <li>ThreadPriorityNormal,
142         <li>ThreadPriorityBelowNormal,
143         <li>ThreadPriorityLowest,
144         <li>ThreadPriorityUnknown (returned if thread is killed)
145     </ul>
146     */
147     TThreadPriority SAL_CALL getPriority();
148 
149     TThreadIdentifier SAL_CALL getIdentifier() const;
150 
151     static TThreadIdentifier SAL_CALL getCurrentIdentifier();
152 
153     /** Let thread sleep a specified amount of time.
154         @param Delay specifies the number of time to sleep.
155     */
156     TThreadSleep SAL_CALL sleep(const TimeValue& Delay);
157 
158     /** Awake the sleeping thread.
159         @returns False if at least one of the handles is invalid
160         or the thread is not sleeping.
161     */
162     sal_Bool SAL_CALL awake();
163 
164     /** Let current thread wait a specified amount of time.
165         @param Delay specifies the number of time
166         to wait. Note, if you need to interrupt the waiting operation
167         use sleep instead.
168     */
169     static void SAL_CALL wait(const TimeValue& Delay);
170 
171     /** Reschedules threads.
172         Call within your loop if you
173         want other threads offer some processing time.
174         This method is static, so it might be used by the
175         main-thread.
176     */
177     static void SAL_CALL yield();
178 
179 protected:
180 
181     /// Working method which should be overridden.
182     virtual void SAL_CALL run() = 0;
183 
184     /** Checks if thread should terminate.
185         isTerminationRequested() will return True if someone called
186         terminate().
187         @return True if thread should terminate, False if he can continue.
188     */
189     virtual sal_Bool SAL_CALL schedule();
190 
191     /** Called when run() is done.
192         You might want to override it to do some cleanup.
193     */
194     virtual void SAL_CALL onTerminated();
195 
196 protected:
197     oslThread m_hThread;
198     sal_Bool   m_bTerminating;
199 
200     friend void threadWorkerFunction_impl(void *);
201 };
202 
203 class VOS_DLLPUBLIC OThreadData : public vos::OObject
204 {
205     VOS_DECLARE_CLASSINFO(VOS_NAMESPACE(OThreadData, vos));
206 
207 public:
208     /// Create a thread specific local data key
209     OThreadData( oslThreadKeyCallbackFunction = 0 );
210 
211     /// Destroy a thread specific local data key
212     virtual ~OThreadData();
213 
214     /** Set the data associated with the data key.
215         @returns True if operation was successful
216     */
217     sal_Bool SAL_CALL setData(void *pData);
218 
219     /** Get the data associated with the data key.
220         @returns The data associated with the data key or
221         NULL if no data was set
222     */
223     void* SAL_CALL getData();
224 
225 protected:
226     oslThreadKey m_hKey;
227 };
228 
229 }
230 
231 #endif // _VOS_THREAD_HXX_
232