xref: /trunk/main/sal/inc/osl/thread.hxx (revision d8dff77764cb74143fabc617dc8ee25d946bae78)
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 _THREAD_HXX_
25 #define _THREAD_HXX_
26 
27 #ifdef __cplusplus
28 
29 #include <osl/time.h>
30 
31 
32 #include <osl/diagnose.h>
33 #include <osl/thread.h>
34 #include <rtl/alloc.h>
35 
36 namespace osl
37 {
38 /** threadFunc is the function which is executed by the threads
39     created by the osl::Thread class. The function's signature
40     matches the one of oslWorkerFunction which is declared in
41     osl/thread.h .
42 */
43 extern "C" inline void SAL_CALL threadFunc( void* param);
44 
45 class Thread
46 {
47     Thread( const Thread& );
48     Thread& operator= ( const Thread& );
49 public:
50     // these are here to force memory de/allocation to sal lib.
51     inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW (())
52         { return ::rtl_allocateMemory( nSize ); }
53     inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW (())
54         { ::rtl_freeMemory( pMem ); }
55     inline static void * SAL_CALL operator new( size_t, void * pMem ) SAL_THROW (())
56         { return pMem; }
57     inline static void SAL_CALL operator delete( void *, void * ) SAL_THROW (())
58         {}
59 
60     Thread(): m_hThread(0){}
61 
62     virtual ~Thread()
63     {
64         osl_destroyThread( m_hThread);
65     }
66 
67     sal_Bool SAL_CALL create()
68     {
69         OSL_ASSERT(m_hThread == 0); // only one running thread per instance
70         if( m_hThread )
71             return sal_False;
72 
73         m_hThread = osl_createSuspendedThread( threadFunc, (void*)this);
74         if( m_hThread )
75             osl_resumeThread(m_hThread);
76 
77         return m_hThread != 0;
78     }
79 
80     sal_Bool SAL_CALL createSuspended()
81     {
82         OSL_ASSERT(m_hThread == 0); // only one running thread per instance
83         if( m_hThread )
84             return sal_False;
85 
86         m_hThread= osl_createSuspendedThread( threadFunc, (void*)this);
87 
88         return m_hThread != 0;
89     }
90 
91     virtual void SAL_CALL suspend()
92     {
93         if( m_hThread )
94             osl_suspendThread(m_hThread);
95     }
96 
97     virtual void SAL_CALL resume()
98     {
99         if( m_hThread )
100             osl_resumeThread(m_hThread);
101     }
102 
103     virtual void SAL_CALL terminate()
104     {
105         if( m_hThread )
106             osl_terminateThread(m_hThread);
107     }
108 
109     virtual void SAL_CALL join()
110     {
111         osl_joinWithThread(m_hThread);
112     }
113 
114     sal_Bool SAL_CALL isRunning() const
115     {
116         return osl_isThreadRunning(m_hThread);
117     }
118 
119     void SAL_CALL setPriority( oslThreadPriority Priority)
120     {
121         if( m_hThread )
122             osl_setThreadPriority(m_hThread, Priority);
123     }
124 
125     oslThreadPriority SAL_CALL getPriority() const
126     {
127         return m_hThread ? osl_getThreadPriority(m_hThread) : osl_Thread_PriorityUnknown;
128     }
129 
130     oslThreadIdentifier SAL_CALL getIdentifier() const
131     {
132         return osl_getThreadIdentifier(m_hThread);
133     }
134 
135     static oslThreadIdentifier SAL_CALL getCurrentIdentifier()
136     {
137         return osl_getThreadIdentifier(0);
138     }
139 
140     static void SAL_CALL wait(const TimeValue& Delay)
141     {
142         osl_waitThread(&Delay);
143     }
144 
145     static void SAL_CALL yield()
146     {
147         osl_yieldThread();
148     }
149 
150     static inline void setName(char const * name) throw () {
151         osl_setThreadName(name);
152     }
153 
154     virtual sal_Bool SAL_CALL schedule()
155     {
156         return m_hThread ? osl_scheduleThread(m_hThread) : sal_False;
157     }
158 
159     SAL_CALL operator oslThread() const
160     {
161         return m_hThread;
162     }
163 
164 protected:
165 
166     /** The thread functions calls the protected functions
167         run and onTerminated.
168     */
169     friend void SAL_CALL threadFunc( void* param);
170 
171     virtual void SAL_CALL run() = 0;
172 
173     virtual void SAL_CALL onTerminated()
174     {
175     }
176 
177 private:
178     oslThread m_hThread;
179 };
180 
181 extern "C" inline void SAL_CALL threadFunc( void* param)
182 {
183         Thread* pObj= (Thread*)param;
184         pObj->run();
185         pObj->onTerminated();
186 }
187 
188 class ThreadData
189 {
190     ThreadData( const ThreadData& );
191     ThreadData& operator= (const ThreadData& );
192 public:
193     /// Create a thread specific local data key
194     ThreadData( oslThreadKeyCallbackFunction pCallback= 0 )
195     {
196         m_hKey = osl_createThreadKey( pCallback );
197     }
198 
199     /// Destroy a thread specific local data key
200     ~ThreadData()
201     {
202         osl_destroyThreadKey(m_hKey);
203     }
204 
205     /** Set the data associated with the data key.
206         @returns True if operation was successful
207     */
208     sal_Bool SAL_CALL setData(void *pData)
209     {
210         return (osl_setThreadKeyData(m_hKey, pData));
211     }
212 
213     /** Get the data associated with the data key.
214         @returns The data associated with the data key or
215         NULL if no data was set
216     */
217     void* SAL_CALL getData()
218     {
219         return osl_getThreadKeyData(m_hKey);
220     }
221 
222     operator oslThreadKey() const
223     {
224         return m_hKey;
225     }
226 
227 private:
228     oslThreadKey m_hKey;
229 };
230 
231 } // end namespace osl
232 #endif
233 #endif
234