xref: /aoo42x/main/sal/inc/osl/thread.hxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef _THREAD_HXX_
29 #define _THREAD_HXX_
30 
31 #ifdef __cplusplus
32 
33 #include <osl/time.h>
34 
35 
36 #include <osl/diagnose.h>
37 #include <osl/thread.h>
38 #include <rtl/alloc.h>
39 
40 namespace osl
41 {
42 /** threadFunc is the function which is executed by the threads
43     created by the osl::Thread class. The function's signature
44     matches the one of oslWorkerFunction which is declared in
45     osl/thread.h .
46 */
47 extern "C" inline void SAL_CALL threadFunc( void* param);
48 
49 class Thread
50 {
51     Thread( const Thread& );
52     Thread& operator= ( const Thread& );
53 public:
54 	// these are here to force memory de/allocation to sal lib.
55 	inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW (())
56 		{ return ::rtl_allocateMemory( nSize ); }
57 	inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW (())
58 		{ ::rtl_freeMemory( pMem ); }
59 	inline static void * SAL_CALL operator new( size_t, void * pMem ) SAL_THROW (())
60 		{ return pMem; }
61 	inline static void SAL_CALL operator delete( void *, void * ) SAL_THROW (())
62 		{}
63 
64     Thread(): m_hThread(0){}
65 
66     virtual  ~Thread()
67     {
68         osl_destroyThread( m_hThread);
69     }
70 
71     sal_Bool SAL_CALL create()
72     {
73 	    OSL_ASSERT(m_hThread == 0);	// only one running thread per instance
74        	if (m_hThread)
75 			return sal_False;
76 
77 	    m_hThread = osl_createSuspendedThread( threadFunc, (void*)this);
78 	    if ( m_hThread )
79 		    osl_resumeThread(m_hThread);
80 
81 	    return m_hThread != 0;
82     }
83 
84     sal_Bool SAL_CALL createSuspended()
85     {
86 	    OSL_ASSERT(m_hThread == 0);	// only one running thread per instance
87         if( m_hThread)
88             return sal_False;
89 	    m_hThread= osl_createSuspendedThread( threadFunc,
90 										     (void*)this);
91 	    return m_hThread != 0;
92     }
93 
94     virtual void SAL_CALL suspend()
95     {
96         if( m_hThread )
97             osl_suspendThread(m_hThread);
98     }
99 
100     virtual void SAL_CALL resume()
101     {
102         if( m_hThread )
103             osl_resumeThread(m_hThread);
104     }
105 
106     virtual void SAL_CALL terminate()
107     {
108         if( m_hThread )
109             osl_terminateThread(m_hThread);
110     }
111 
112     virtual void SAL_CALL join()
113     {
114         osl_joinWithThread(m_hThread);
115     }
116 
117     sal_Bool SAL_CALL isRunning() const
118     {
119 	    return osl_isThreadRunning(m_hThread);
120     }
121 
122     void SAL_CALL setPriority( oslThreadPriority Priority)
123     {
124         if( m_hThread )
125             osl_setThreadPriority(m_hThread, Priority);
126     }
127 
128     oslThreadPriority SAL_CALL getPriority() const
129     {
130 	    return m_hThread ? osl_getThreadPriority(m_hThread) : osl_Thread_PriorityUnknown;
131     }
132 
133     oslThreadIdentifier SAL_CALL getIdentifier() const
134     {
135 	    return osl_getThreadIdentifier(m_hThread);
136     }
137 
138     static oslThreadIdentifier SAL_CALL getCurrentIdentifier()
139     {
140 	    return osl_getThreadIdentifier(0);
141     }
142 
143     static void SAL_CALL wait(const TimeValue& Delay)
144     {
145 	    osl_waitThread(&Delay);
146     }
147 
148     static void SAL_CALL yield()
149     {
150 	    osl_yieldThread();
151     }
152 
153     static inline void setName(char const * name) throw () {
154         osl_setThreadName(name);
155     }
156 
157     virtual sal_Bool SAL_CALL schedule()
158     {
159 	    return m_hThread ? osl_scheduleThread(m_hThread) : sal_False;
160     }
161 
162     SAL_CALL operator oslThread() const
163     {
164         return m_hThread;
165     }
166 
167 protected:
168 
169     /** The thread functions calls the protected functions
170         run and onTerminated.
171     */
172     friend void SAL_CALL threadFunc( void* param);
173 
174     virtual void SAL_CALL run() = 0;
175 
176     virtual void SAL_CALL onTerminated()
177     {
178     }
179 
180 private:
181     oslThread m_hThread;
182 };
183 
184 extern "C" inline void SAL_CALL threadFunc( void* param)
185 {
186         Thread* pObj= (Thread*)param;
187         pObj->run();
188 	    pObj->onTerminated();
189 }
190 
191 class ThreadData
192 {
193     ThreadData( const ThreadData& );
194     ThreadData& operator= (const ThreadData& );
195 public:
196  	/// Create a thread specific local data key
197     ThreadData( oslThreadKeyCallbackFunction pCallback= 0 )
198     {
199         m_hKey = osl_createThreadKey( pCallback );
200     }
201 
202 	/// Destroy a thread specific local data key
203 	~ThreadData()
204     {
205        	osl_destroyThreadKey(m_hKey);
206     }
207 
208 	/** Set the data associated with the data key.
209 		@returns True if operation was successfull
210 	*/
211 	sal_Bool SAL_CALL setData(void *pData)
212     {
213        	return (osl_setThreadKeyData(m_hKey, pData));
214     }
215 
216 	/** Get the data associated with the data key.
217 		@returns The data asscoitaed with the data key or
218 		NULL if no data was set
219 	*/
220 	void* SAL_CALL getData()
221     {
222        	return osl_getThreadKeyData(m_hKey);
223     }
224 
225     operator oslThreadKey() const
226     {
227         return m_hKey;
228     }
229 
230 private:
231 	oslThreadKey m_hKey;
232 };
233 
234 } // end namespace osl
235 #endif
236 #endif
237