xref: /aoo42x/main/sal/inc/osl/thread.hxx (revision 88e06183)
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 		m_hThread= osl_createSuspendedThread( threadFunc,
86 											(void*)this);
87 		return m_hThread != 0;
88 	}
89 
90 	virtual void SAL_CALL suspend()
91 	{
92 		if( m_hThread )
93 			osl_suspendThread(m_hThread);
94 	}
95 
96 	virtual void SAL_CALL resume()
97 	{
98 		if( m_hThread )
99 			osl_resumeThread(m_hThread);
100 	}
101 
102 	virtual void SAL_CALL terminate()
103 	{
104 		if( m_hThread )
105 			osl_terminateThread(m_hThread);
106 	}
107 
108 	virtual void SAL_CALL join()
109 	{
110 		osl_joinWithThread(m_hThread);
111 	}
112 
113 	sal_Bool SAL_CALL isRunning() const
114 	{
115 		return osl_isThreadRunning(m_hThread);
116 	}
117 
118 	void SAL_CALL setPriority( oslThreadPriority Priority)
119 	{
120 		if( m_hThread )
121 			osl_setThreadPriority(m_hThread, Priority);
122 	}
123 
124 	oslThreadPriority SAL_CALL getPriority() const
125 	{
126 		return m_hThread ? osl_getThreadPriority(m_hThread) : osl_Thread_PriorityUnknown;
127 	}
128 
129 	oslThreadIdentifier SAL_CALL getIdentifier() const
130 	{
131 		return osl_getThreadIdentifier(m_hThread);
132 	}
133 
134 	static oslThreadIdentifier SAL_CALL getCurrentIdentifier()
135 	{
136 		return osl_getThreadIdentifier(0);
137 	}
138 
139 	static void SAL_CALL wait(const TimeValue& Delay)
140 	{
141 		osl_waitThread(&Delay);
142 	}
143 
144 	static void SAL_CALL yield()
145 	{
146 		osl_yieldThread();
147 	}
148 
149 	static inline void setName(char const * name) throw () {
150 		osl_setThreadName(name);
151 	}
152 
153 	virtual sal_Bool SAL_CALL schedule()
154 	{
155 		return m_hThread ? osl_scheduleThread(m_hThread) : sal_False;
156 	}
157 
158 	SAL_CALL operator oslThread() const
159 	{
160 		return m_hThread;
161 	}
162 
163 protected:
164 
165 	/** The thread functions calls the protected functions
166 		run and onTerminated.
167 	*/
168 	friend void SAL_CALL threadFunc( void* param);
169 
170 	virtual void SAL_CALL run() = 0;
171 
172 	virtual void SAL_CALL onTerminated()
173 	{
174 	}
175 
176 private:
177 	oslThread m_hThread;
178 };
179 
180 extern "C" inline void SAL_CALL threadFunc( void* param)
181 {
182 		Thread* pObj= (Thread*)param;
183 		pObj->run();
184 		pObj->onTerminated();
185 }
186 
187 class ThreadData
188 {
189 	ThreadData( const ThreadData& );
190 	ThreadData& operator= (const ThreadData& );
191 public:
192  	/// Create a thread specific local data key
193 	ThreadData( oslThreadKeyCallbackFunction pCallback= 0 )
194 	{
195 		m_hKey = osl_createThreadKey( pCallback );
196 	}
197 
198 	/// Destroy a thread specific local data key
199 	~ThreadData()
200 	{
201 		osl_destroyThreadKey(m_hKey);
202 	}
203 
204 	/** Set the data associated with the data key.
205 		@returns True if operation was successful
206 	*/
207 	sal_Bool SAL_CALL setData(void *pData)
208 	{
209 		return (osl_setThreadKeyData(m_hKey, pData));
210 	}
211 
212 	/** Get the data associated with the data key.
213 		@returns The data associated with the data key or
214 		NULL if no data was set
215 	*/
216 	void* SAL_CALL getData()
217 	{
218 		return osl_getThreadKeyData(m_hKey);
219 	}
220 
221 	operator oslThreadKey() const
222 	{
223 		return m_hKey;
224 	}
225 
226 private:
227 	oslThreadKey m_hKey;
228 };
229 
230 } // end namespace osl
231 #endif
232 #endif
233