xref: /aoo41x/main/sal/osl/w32/thread.c (revision 647f063d)
1*647f063dSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*647f063dSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*647f063dSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*647f063dSAndrew Rist  * distributed with this work for additional information
6*647f063dSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*647f063dSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*647f063dSAndrew Rist  * "License"); you may not use this file except in compliance
9*647f063dSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*647f063dSAndrew Rist  *
11*647f063dSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*647f063dSAndrew Rist  *
13*647f063dSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*647f063dSAndrew Rist  * software distributed under the License is distributed on an
15*647f063dSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*647f063dSAndrew Rist  * KIND, either express or implied.  See the License for the
17*647f063dSAndrew Rist  * specific language governing permissions and limitations
18*647f063dSAndrew Rist  * under the License.
19*647f063dSAndrew Rist  *
20*647f063dSAndrew Rist  *************************************************************/
21*647f063dSAndrew Rist 
22*647f063dSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "system.h"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <osl/diagnose.h>
27cdf0e10cSrcweir #include <osl/thread.h>
28cdf0e10cSrcweir #include <rtl/alloc.h>
29cdf0e10cSrcweir #include <osl/time.h>
30cdf0e10cSrcweir #include <osl/interlck.h>
31cdf0e10cSrcweir #include <rtl/tencinfo.h>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir /*
34cdf0e10cSrcweir 	Thread-data structure hidden behind oslThread:
35cdf0e10cSrcweir */
36cdf0e10cSrcweir typedef struct _osl_TThreadImpl
37cdf0e10cSrcweir {
38cdf0e10cSrcweir 	HANDLE				m_hThread;		/* OS-handle used for all thread-functions */
39cdf0e10cSrcweir 	unsigned			m_ThreadId;		/* identifier for this thread */
40cdf0e10cSrcweir 	sal_Int32			m_nTerminationRequested;
41cdf0e10cSrcweir 	oslWorkerFunction	m_WorkerFunction;
42cdf0e10cSrcweir 	void*				m_pData;
43cdf0e10cSrcweir 
44cdf0e10cSrcweir } osl_TThreadImpl;
45cdf0e10cSrcweir 
46cdf0e10cSrcweir #define THREADIMPL_FLAGS_TERMINATE	0x0001
47cdf0e10cSrcweir 
48cdf0e10cSrcweir static unsigned __stdcall oslWorkerWrapperFunction(void* pData);
49cdf0e10cSrcweir static oslThread oslCreateThread(oslWorkerFunction pWorker, void* pThreadData, sal_uInt32 nFlags);
50cdf0e10cSrcweir 
51cdf0e10cSrcweir /*****************************************************************************/
52cdf0e10cSrcweir /* oslWorkerWrapperFunction */
53cdf0e10cSrcweir /*****************************************************************************/
oslWorkerWrapperFunction(void * pData)54cdf0e10cSrcweir static unsigned __stdcall oslWorkerWrapperFunction(void* pData)
55cdf0e10cSrcweir {
56cdf0e10cSrcweir 	osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)pData;
57cdf0e10cSrcweir 
58cdf0e10cSrcweir 	/* Initialize COM */
59cdf0e10cSrcweir 
60cdf0e10cSrcweir     CoInitializeEx(NULL, COINIT_MULTITHREADED);
61cdf0e10cSrcweir 
62cdf0e10cSrcweir 	/* call worker-function with data */
63cdf0e10cSrcweir 
64cdf0e10cSrcweir 	pThreadImpl->m_WorkerFunction(pThreadImpl->m_pData);
65cdf0e10cSrcweir 
66cdf0e10cSrcweir 	CoUninitialize();
67cdf0e10cSrcweir 
68cdf0e10cSrcweir 	return (0);
69cdf0e10cSrcweir }
70cdf0e10cSrcweir 
71cdf0e10cSrcweir /*****************************************************************************/
72cdf0e10cSrcweir /* oslCreateThread */
73cdf0e10cSrcweir /*****************************************************************************/
oslCreateThread(oslWorkerFunction pWorker,void * pThreadData,sal_uInt32 nFlags)74cdf0e10cSrcweir static oslThread oslCreateThread(oslWorkerFunction pWorker,
75cdf0e10cSrcweir                                  void* pThreadData,
76cdf0e10cSrcweir                                  sal_uInt32 nFlags)
77cdf0e10cSrcweir {
78cdf0e10cSrcweir 	osl_TThreadImpl* pThreadImpl;
79cdf0e10cSrcweir 
80cdf0e10cSrcweir 	/* alloc mem. for our internal data structure */
81cdf0e10cSrcweir 	pThreadImpl= malloc(sizeof(osl_TThreadImpl));
82cdf0e10cSrcweir 
83cdf0e10cSrcweir 	OSL_ASSERT(pThreadImpl);
84cdf0e10cSrcweir 
85cdf0e10cSrcweir     if ( pThreadImpl == 0 )
86cdf0e10cSrcweir     {
87cdf0e10cSrcweir         return 0;
88cdf0e10cSrcweir     }
89cdf0e10cSrcweir 
90cdf0e10cSrcweir 	pThreadImpl->m_WorkerFunction= pWorker;
91cdf0e10cSrcweir 	pThreadImpl->m_pData= pThreadData;
92cdf0e10cSrcweir 	pThreadImpl->m_nTerminationRequested= 0;
93cdf0e10cSrcweir 
94cdf0e10cSrcweir 	pThreadImpl->m_hThread=
95cdf0e10cSrcweir 		(HANDLE)_beginthreadex(NULL,						/* no security */
96cdf0e10cSrcweir 							   0,							/* default stack-size */
97cdf0e10cSrcweir 							   oslWorkerWrapperFunction,	/* worker-function */
98cdf0e10cSrcweir 							   pThreadImpl,					/* provide worker-function with data */
99cdf0e10cSrcweir 							   nFlags,						/* start thread immediately or suspended */
100cdf0e10cSrcweir 							   &pThreadImpl->m_ThreadId);
101cdf0e10cSrcweir 
102cdf0e10cSrcweir 	if(pThreadImpl->m_hThread == 0)
103cdf0e10cSrcweir 	{
104cdf0e10cSrcweir 		/* create failed */
105cdf0e10cSrcweir 		free(pThreadImpl);
106cdf0e10cSrcweir 		return 0;
107cdf0e10cSrcweir 	}
108cdf0e10cSrcweir 
109cdf0e10cSrcweir 	return (oslThread)pThreadImpl;
110cdf0e10cSrcweir }
111cdf0e10cSrcweir 
112cdf0e10cSrcweir /*****************************************************************************/
113cdf0e10cSrcweir /* osl_createThread */
114cdf0e10cSrcweir /*****************************************************************************/
osl_createThread(oslWorkerFunction pWorker,void * pThreadData)115cdf0e10cSrcweir oslThread SAL_CALL osl_createThread(oslWorkerFunction pWorker,
116cdf0e10cSrcweir                                     void* pThreadData)
117cdf0e10cSrcweir {
118cdf0e10cSrcweir     return oslCreateThread(pWorker, pThreadData, 0);
119cdf0e10cSrcweir }
120cdf0e10cSrcweir 
121cdf0e10cSrcweir /*****************************************************************************/
122cdf0e10cSrcweir /* osl_createSuspendedThread */
123cdf0e10cSrcweir /*****************************************************************************/
osl_createSuspendedThread(oslWorkerFunction pWorker,void * pThreadData)124cdf0e10cSrcweir oslThread SAL_CALL osl_createSuspendedThread(oslWorkerFunction pWorker,
125cdf0e10cSrcweir                                              void* pThreadData)
126cdf0e10cSrcweir {
127cdf0e10cSrcweir     return oslCreateThread(pWorker, pThreadData, CREATE_SUSPENDED);
128cdf0e10cSrcweir }
129cdf0e10cSrcweir 
130cdf0e10cSrcweir /*****************************************************************************/
131cdf0e10cSrcweir /* osl_getThreadIdentifier */
132cdf0e10cSrcweir /*****************************************************************************/
osl_getThreadIdentifier(oslThread Thread)133cdf0e10cSrcweir oslThreadIdentifier SAL_CALL osl_getThreadIdentifier(oslThread Thread)
134cdf0e10cSrcweir {
135cdf0e10cSrcweir 	osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
136cdf0e10cSrcweir 
137cdf0e10cSrcweir 	if (pThreadImpl != NULL)
138cdf0e10cSrcweir 		return ((oslThreadIdentifier)pThreadImpl->m_ThreadId);
139cdf0e10cSrcweir 	else
140cdf0e10cSrcweir 		return ((oslThreadIdentifier)GetCurrentThreadId());
141cdf0e10cSrcweir }
142cdf0e10cSrcweir 
143cdf0e10cSrcweir /*****************************************************************************/
144cdf0e10cSrcweir /* osl_destroyThread */
145cdf0e10cSrcweir /*****************************************************************************/
osl_destroyThread(oslThread Thread)146cdf0e10cSrcweir void SAL_CALL osl_destroyThread(oslThread Thread)
147cdf0e10cSrcweir {
148cdf0e10cSrcweir 	osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
149cdf0e10cSrcweir 
150cdf0e10cSrcweir 	if (Thread == 0) /* valid ptr? */
151cdf0e10cSrcweir 	{
152cdf0e10cSrcweir 		/* thread already destroyed or not created */
153cdf0e10cSrcweir 		return;
154cdf0e10cSrcweir 	}
155cdf0e10cSrcweir 
156cdf0e10cSrcweir     /* !!!! _exitthreadex does _not_ call CloseHandle !!! */
157cdf0e10cSrcweir     CloseHandle( pThreadImpl->m_hThread );
158cdf0e10cSrcweir 
159cdf0e10cSrcweir 	/* free memory */
160cdf0e10cSrcweir 	free(Thread);
161cdf0e10cSrcweir }
162cdf0e10cSrcweir 
163cdf0e10cSrcweir /*****************************************************************************/
164cdf0e10cSrcweir /* osl_resumeThread */
165cdf0e10cSrcweir /*****************************************************************************/
osl_resumeThread(oslThread Thread)166cdf0e10cSrcweir void SAL_CALL osl_resumeThread(oslThread Thread)
167cdf0e10cSrcweir {
168cdf0e10cSrcweir 	osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
169cdf0e10cSrcweir 
170cdf0e10cSrcweir 	OSL_ASSERT(pThreadImpl);		/* valid ptr? */
171cdf0e10cSrcweir 
172cdf0e10cSrcweir 	ResumeThread(pThreadImpl->m_hThread);
173cdf0e10cSrcweir }
174cdf0e10cSrcweir 
175cdf0e10cSrcweir /*****************************************************************************/
176cdf0e10cSrcweir /* osl_suspendThread */
177cdf0e10cSrcweir /*****************************************************************************/
osl_suspendThread(oslThread Thread)178cdf0e10cSrcweir void SAL_CALL osl_suspendThread(oslThread Thread)
179cdf0e10cSrcweir {
180cdf0e10cSrcweir 	osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
181cdf0e10cSrcweir 
182cdf0e10cSrcweir 	OSL_ASSERT(pThreadImpl);		/* valid ptr? */
183cdf0e10cSrcweir 
184cdf0e10cSrcweir 	SuspendThread(pThreadImpl->m_hThread);
185cdf0e10cSrcweir }
186cdf0e10cSrcweir 
187cdf0e10cSrcweir /*****************************************************************************/
188cdf0e10cSrcweir /* osl_setThreadPriority */
189cdf0e10cSrcweir /*****************************************************************************/
osl_setThreadPriority(oslThread Thread,oslThreadPriority Priority)190cdf0e10cSrcweir void SAL_CALL osl_setThreadPriority(oslThread Thread,
191cdf0e10cSrcweir 						   oslThreadPriority Priority)
192cdf0e10cSrcweir {
193cdf0e10cSrcweir 	int winPriority;
194cdf0e10cSrcweir 	osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
195cdf0e10cSrcweir 
196cdf0e10cSrcweir 	OSL_ASSERT(pThreadImpl);		/* valid ptr? */
197cdf0e10cSrcweir 
198cdf0e10cSrcweir 
199cdf0e10cSrcweir 	/*	map enum to WIN32 levels
200cdf0e10cSrcweir 		it would be faster and more elegant to preset
201cdf0e10cSrcweir 		the enums, but that would require an #ifdef in
202cdf0e10cSrcweir 		the exported header, which is not desired.
203cdf0e10cSrcweir 	*/
204cdf0e10cSrcweir 	switch(Priority) {
205cdf0e10cSrcweir 
206cdf0e10cSrcweir 	case osl_Thread_PriorityHighest:
207cdf0e10cSrcweir 		winPriority= THREAD_PRIORITY_HIGHEST;
208cdf0e10cSrcweir 		break;
209cdf0e10cSrcweir 
210cdf0e10cSrcweir 	case osl_Thread_PriorityAboveNormal:
211cdf0e10cSrcweir 		winPriority= THREAD_PRIORITY_ABOVE_NORMAL;
212cdf0e10cSrcweir 		break;
213cdf0e10cSrcweir 
214cdf0e10cSrcweir 	case osl_Thread_PriorityNormal:
215cdf0e10cSrcweir 		winPriority= THREAD_PRIORITY_NORMAL;
216cdf0e10cSrcweir 		break;
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 	case osl_Thread_PriorityBelowNormal:
219cdf0e10cSrcweir 		winPriority= THREAD_PRIORITY_BELOW_NORMAL;
220cdf0e10cSrcweir 		break;
221cdf0e10cSrcweir 
222cdf0e10cSrcweir 	case osl_Thread_PriorityLowest:
223cdf0e10cSrcweir 		winPriority= THREAD_PRIORITY_LOWEST;
224cdf0e10cSrcweir 		break;
225cdf0e10cSrcweir 
226cdf0e10cSrcweir 	case osl_Thread_PriorityUnknown:
227cdf0e10cSrcweir 		OSL_ASSERT(FALSE);		/* only fools try this...*/
228cdf0e10cSrcweir 
229cdf0e10cSrcweir 		/* let release-version behave friendly */
230cdf0e10cSrcweir 		return;
231cdf0e10cSrcweir 
232cdf0e10cSrcweir 	default:
233cdf0e10cSrcweir 		OSL_ASSERT(FALSE);		/* enum expanded, but forgotten here...*/
234cdf0e10cSrcweir 
235cdf0e10cSrcweir 		/* let release-version behave friendly */
236cdf0e10cSrcweir 		return;
237cdf0e10cSrcweir 	}
238cdf0e10cSrcweir 
239cdf0e10cSrcweir 	SetThreadPriority(pThreadImpl->m_hThread, winPriority);
240cdf0e10cSrcweir }
241cdf0e10cSrcweir 
242cdf0e10cSrcweir /*****************************************************************************/
243cdf0e10cSrcweir /* osl_getThreadPriority  */
244cdf0e10cSrcweir /*****************************************************************************/
osl_getThreadPriority(const oslThread Thread)245cdf0e10cSrcweir oslThreadPriority SAL_CALL osl_getThreadPriority(const oslThread Thread)
246cdf0e10cSrcweir {
247cdf0e10cSrcweir 	int winPriority;
248cdf0e10cSrcweir 	oslThreadPriority Priority;
249cdf0e10cSrcweir 
250cdf0e10cSrcweir 	osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
251cdf0e10cSrcweir 
252cdf0e10cSrcweir 	/* invalid arguments ?*/
253cdf0e10cSrcweir 	if(pThreadImpl==0 || pThreadImpl->m_hThread==0)
254cdf0e10cSrcweir 	{
255cdf0e10cSrcweir 		return osl_Thread_PriorityUnknown;
256cdf0e10cSrcweir 	}
257cdf0e10cSrcweir 
258cdf0e10cSrcweir 	winPriority=
259cdf0e10cSrcweir 		GetThreadPriority(pThreadImpl->m_hThread);
260cdf0e10cSrcweir 
261cdf0e10cSrcweir 
262cdf0e10cSrcweir 	if(winPriority == THREAD_PRIORITY_ERROR_RETURN)
263cdf0e10cSrcweir 	{
264cdf0e10cSrcweir 		return osl_Thread_PriorityUnknown;
265cdf0e10cSrcweir 	}
266cdf0e10cSrcweir 
267cdf0e10cSrcweir 	/* map WIN32 priority to enum */
268cdf0e10cSrcweir 	switch(winPriority)
269cdf0e10cSrcweir 	{
270cdf0e10cSrcweir 	case THREAD_PRIORITY_TIME_CRITICAL:
271cdf0e10cSrcweir 	case THREAD_PRIORITY_HIGHEST:
272cdf0e10cSrcweir 		Priority= osl_Thread_PriorityHighest;
273cdf0e10cSrcweir 		break;
274cdf0e10cSrcweir 
275cdf0e10cSrcweir 	case THREAD_PRIORITY_ABOVE_NORMAL:
276cdf0e10cSrcweir 		Priority= osl_Thread_PriorityAboveNormal;
277cdf0e10cSrcweir 		break;
278cdf0e10cSrcweir 
279cdf0e10cSrcweir 	case THREAD_PRIORITY_NORMAL:
280cdf0e10cSrcweir 		Priority= osl_Thread_PriorityNormal;
281cdf0e10cSrcweir 		break;
282cdf0e10cSrcweir 
283cdf0e10cSrcweir 	case THREAD_PRIORITY_BELOW_NORMAL:
284cdf0e10cSrcweir 		Priority= osl_Thread_PriorityBelowNormal;
285cdf0e10cSrcweir 		break;
286cdf0e10cSrcweir 
287cdf0e10cSrcweir 	case THREAD_PRIORITY_IDLE:
288cdf0e10cSrcweir 	case THREAD_PRIORITY_LOWEST:
289cdf0e10cSrcweir 		Priority= osl_Thread_PriorityLowest;
290cdf0e10cSrcweir 		break;
291cdf0e10cSrcweir 
292cdf0e10cSrcweir 	default:
293cdf0e10cSrcweir 		OSL_ASSERT(FALSE);		/* WIN32 API changed, incorporate new prio-level! */
294cdf0e10cSrcweir 
295cdf0e10cSrcweir 		/* release-version behaves friendly */
296cdf0e10cSrcweir 		Priority= osl_Thread_PriorityUnknown;
297cdf0e10cSrcweir 	}
298cdf0e10cSrcweir 
299cdf0e10cSrcweir 	return Priority;
300cdf0e10cSrcweir }
301cdf0e10cSrcweir 
302cdf0e10cSrcweir /*****************************************************************************/
303cdf0e10cSrcweir /* osl_isThreadRunning */
304cdf0e10cSrcweir /*****************************************************************************/
osl_isThreadRunning(const oslThread Thread)305cdf0e10cSrcweir sal_Bool SAL_CALL osl_isThreadRunning(const oslThread Thread)
306cdf0e10cSrcweir {
307cdf0e10cSrcweir 	osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 	/* invalid arguments ?*/
310cdf0e10cSrcweir 	if(pThreadImpl==0 || pThreadImpl->m_hThread==0)
311cdf0e10cSrcweir 	{
312cdf0e10cSrcweir 		return sal_False;
313cdf0e10cSrcweir 	}
314cdf0e10cSrcweir 
315cdf0e10cSrcweir 	return (sal_Bool)(WaitForSingleObject(pThreadImpl->m_hThread, 0) != WAIT_OBJECT_0);
316cdf0e10cSrcweir }
317cdf0e10cSrcweir 
318cdf0e10cSrcweir /*****************************************************************************/
319cdf0e10cSrcweir /* osl_joinWithThread */
320cdf0e10cSrcweir /*****************************************************************************/
osl_joinWithThread(oslThread Thread)321cdf0e10cSrcweir void SAL_CALL osl_joinWithThread(oslThread Thread)
322cdf0e10cSrcweir {
323cdf0e10cSrcweir 	osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
324cdf0e10cSrcweir 
325cdf0e10cSrcweir 	/* invalid arguments?*/
326cdf0e10cSrcweir 	if(pThreadImpl==0 || pThreadImpl->m_hThread==0)
327cdf0e10cSrcweir 	{
328cdf0e10cSrcweir 		/* assume thread is not running */
329cdf0e10cSrcweir 		return;
330cdf0e10cSrcweir 	}
331cdf0e10cSrcweir 
332cdf0e10cSrcweir 	WaitForSingleObject(pThreadImpl->m_hThread, INFINITE);
333cdf0e10cSrcweir }
334cdf0e10cSrcweir 
335cdf0e10cSrcweir /*****************************************************************************/
336cdf0e10cSrcweir /* osl_waitThread */
337cdf0e10cSrcweir /*****************************************************************************/
osl_waitThread(const TimeValue * pDelay)338cdf0e10cSrcweir void SAL_CALL osl_waitThread(const TimeValue* pDelay)
339cdf0e10cSrcweir {
340cdf0e10cSrcweir 	if (pDelay)
341cdf0e10cSrcweir 	{
342cdf0e10cSrcweir 		DWORD millisecs = pDelay->Seconds * 1000L + pDelay->Nanosec / 1000000L;
343cdf0e10cSrcweir 
344cdf0e10cSrcweir 		Sleep(millisecs);
345cdf0e10cSrcweir 	}
346cdf0e10cSrcweir }
347cdf0e10cSrcweir 
348cdf0e10cSrcweir /*****************************************************************************/
349cdf0e10cSrcweir /* osl_terminateThread */
350cdf0e10cSrcweir /*****************************************************************************/
osl_terminateThread(oslThread Thread)351cdf0e10cSrcweir void SAL_CALL osl_terminateThread(oslThread Thread)
352cdf0e10cSrcweir {
353cdf0e10cSrcweir 	osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
354cdf0e10cSrcweir 
355cdf0e10cSrcweir 	/* invalid arguments?*/
356cdf0e10cSrcweir 	if (pThreadImpl==0 || pThreadImpl->m_hThread==0)
357cdf0e10cSrcweir 	{
358cdf0e10cSrcweir 		/* assume thread is not running */
359cdf0e10cSrcweir 		return;
360cdf0e10cSrcweir 	}
361cdf0e10cSrcweir 
362cdf0e10cSrcweir     osl_incrementInterlockedCount(&(pThreadImpl->m_nTerminationRequested));
363cdf0e10cSrcweir }
364cdf0e10cSrcweir 
365cdf0e10cSrcweir 
366cdf0e10cSrcweir /*****************************************************************************/
367cdf0e10cSrcweir /* osl_scheduleThread */
368cdf0e10cSrcweir /*****************************************************************************/
osl_scheduleThread(oslThread Thread)369cdf0e10cSrcweir sal_Bool SAL_CALL osl_scheduleThread(oslThread Thread)
370cdf0e10cSrcweir {
371cdf0e10cSrcweir 	osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
372cdf0e10cSrcweir 
373cdf0e10cSrcweir 	osl_yieldThread();
374cdf0e10cSrcweir 
375cdf0e10cSrcweir 	/* invalid arguments?*/
376cdf0e10cSrcweir 	if (pThreadImpl==0 || pThreadImpl->m_hThread==0)
377cdf0e10cSrcweir 	{
378cdf0e10cSrcweir 		/* assume thread is not running */
379cdf0e10cSrcweir 		return sal_False;
380cdf0e10cSrcweir 	}
381cdf0e10cSrcweir 
382cdf0e10cSrcweir 	return (sal_Bool)(0 == pThreadImpl->m_nTerminationRequested);
383cdf0e10cSrcweir }
384cdf0e10cSrcweir 
385cdf0e10cSrcweir /*****************************************************************************/
386cdf0e10cSrcweir /* osl_yieldThread */
387cdf0e10cSrcweir /*****************************************************************************/
osl_yieldThread(void)388cdf0e10cSrcweir void SAL_CALL osl_yieldThread(void)
389cdf0e10cSrcweir {
390cdf0e10cSrcweir 	Sleep(0);
391cdf0e10cSrcweir }
392cdf0e10cSrcweir 
osl_setThreadName(char const * name)393cdf0e10cSrcweir void SAL_CALL osl_setThreadName(char const * name) {
394cdf0e10cSrcweir #ifdef _MSC_VER
395cdf0e10cSrcweir     /* See <http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx>: */
396cdf0e10cSrcweir #pragma pack(push, 8)
397cdf0e10cSrcweir     struct {
398cdf0e10cSrcweir         DWORD dwType;
399cdf0e10cSrcweir         LPCSTR szName;
400cdf0e10cSrcweir         DWORD dwThreadID;
401cdf0e10cSrcweir         DWORD dwFlags;
402cdf0e10cSrcweir     } info;
403cdf0e10cSrcweir #pragma pack(pop)
404cdf0e10cSrcweir     info.dwType = 0x1000;
405cdf0e10cSrcweir     info.szName = name;
406cdf0e10cSrcweir     info.dwThreadID = (DWORD) -1;
407cdf0e10cSrcweir     info.dwFlags = 0;
408cdf0e10cSrcweir     __try {
409cdf0e10cSrcweir         RaiseException(
410cdf0e10cSrcweir             0x406D1388, 0, sizeof info / sizeof (ULONG_PTR),
411cdf0e10cSrcweir             (ULONG_PTR *) &info);
412cdf0e10cSrcweir     } __except (EXCEPTION_EXECUTE_HANDLER) {}
413cdf0e10cSrcweir #else
414cdf0e10cSrcweir     (void) name;
415cdf0e10cSrcweir #endif
416cdf0e10cSrcweir }
417cdf0e10cSrcweir 
418cdf0e10cSrcweir typedef struct _TLS
419cdf0e10cSrcweir {
420cdf0e10cSrcweir 	DWORD							dwIndex;
421cdf0e10cSrcweir 	oslThreadKeyCallbackFunction	pfnCallback;
422cdf0e10cSrcweir 	struct _TLS						*pNext, *pPrev;
423cdf0e10cSrcweir } TLS, *PTLS;
424cdf0e10cSrcweir 
425cdf0e10cSrcweir static	PTLS		g_pThreadKeyList = NULL;
426cdf0e10cSrcweir CRITICAL_SECTION	g_ThreadKeyListCS;
427cdf0e10cSrcweir 
AddKeyToList(PTLS pTls)428cdf0e10cSrcweir static void AddKeyToList( PTLS pTls )
429cdf0e10cSrcweir {
430cdf0e10cSrcweir 	if ( pTls )
431cdf0e10cSrcweir 	{
432cdf0e10cSrcweir 		EnterCriticalSection( &g_ThreadKeyListCS );
433cdf0e10cSrcweir 
434cdf0e10cSrcweir 		pTls->pNext = g_pThreadKeyList;
435cdf0e10cSrcweir 		pTls->pPrev = 0;
436cdf0e10cSrcweir 
437cdf0e10cSrcweir 		if ( g_pThreadKeyList )
438cdf0e10cSrcweir 			g_pThreadKeyList->pPrev = pTls;
439cdf0e10cSrcweir 
440cdf0e10cSrcweir 		g_pThreadKeyList = pTls;
441cdf0e10cSrcweir 
442cdf0e10cSrcweir 		LeaveCriticalSection( &g_ThreadKeyListCS );
443cdf0e10cSrcweir 	}
444cdf0e10cSrcweir }
445cdf0e10cSrcweir 
RemoveKeyFromList(PTLS pTls)446cdf0e10cSrcweir static void RemoveKeyFromList( PTLS pTls )
447cdf0e10cSrcweir {
448cdf0e10cSrcweir 	if ( pTls )
449cdf0e10cSrcweir 	{
450cdf0e10cSrcweir 		EnterCriticalSection( &g_ThreadKeyListCS );
451cdf0e10cSrcweir 		if ( pTls->pPrev )
452cdf0e10cSrcweir 			pTls->pPrev->pNext = pTls->pNext;
453cdf0e10cSrcweir 		else
454cdf0e10cSrcweir 		{
455cdf0e10cSrcweir 			OSL_ASSERT( pTls == g_pThreadKeyList );
456cdf0e10cSrcweir 			g_pThreadKeyList = pTls->pNext;
457cdf0e10cSrcweir 		}
458cdf0e10cSrcweir 
459cdf0e10cSrcweir 		if ( pTls->pNext )
460cdf0e10cSrcweir 			pTls->pNext->pPrev = pTls->pPrev;
461cdf0e10cSrcweir 		LeaveCriticalSection( &g_ThreadKeyListCS );
462cdf0e10cSrcweir 	}
463cdf0e10cSrcweir }
464cdf0e10cSrcweir 
_osl_callThreadKeyCallbackOnThreadDetach(void)465cdf0e10cSrcweir void SAL_CALL _osl_callThreadKeyCallbackOnThreadDetach(void)
466cdf0e10cSrcweir {
467cdf0e10cSrcweir 	PTLS	pTls;
468cdf0e10cSrcweir 
469cdf0e10cSrcweir 
470cdf0e10cSrcweir 	EnterCriticalSection( &g_ThreadKeyListCS );
471cdf0e10cSrcweir 	pTls = g_pThreadKeyList;
472cdf0e10cSrcweir 	while ( pTls )
473cdf0e10cSrcweir 	{
474cdf0e10cSrcweir 		if ( pTls->pfnCallback )
475cdf0e10cSrcweir 		{
476cdf0e10cSrcweir 			void	*pValue	= TlsGetValue( pTls->dwIndex );
477cdf0e10cSrcweir 
478cdf0e10cSrcweir 			if ( pValue )
479cdf0e10cSrcweir 				pTls->pfnCallback( pValue );
480cdf0e10cSrcweir 		}
481cdf0e10cSrcweir 
482cdf0e10cSrcweir 		pTls = pTls->pNext;
483cdf0e10cSrcweir 	}
484cdf0e10cSrcweir 	LeaveCriticalSection( &g_ThreadKeyListCS );
485cdf0e10cSrcweir }
486cdf0e10cSrcweir 
487cdf0e10cSrcweir /*****************************************************************************/
488cdf0e10cSrcweir /* osl_createThreadKey */
489cdf0e10cSrcweir /*****************************************************************************/
osl_createThreadKey(oslThreadKeyCallbackFunction pCallback)490cdf0e10cSrcweir oslThreadKey SAL_CALL osl_createThreadKey(oslThreadKeyCallbackFunction pCallback)
491cdf0e10cSrcweir {
492cdf0e10cSrcweir 	PTLS	pTls = rtl_allocateMemory( sizeof(TLS) );
493cdf0e10cSrcweir 
494cdf0e10cSrcweir 	if ( pTls )
495cdf0e10cSrcweir 	{
496cdf0e10cSrcweir 		pTls->pfnCallback = pCallback;
497cdf0e10cSrcweir 		if ( (DWORD)-1 == (pTls->dwIndex = TlsAlloc()) )
498cdf0e10cSrcweir 		{
499cdf0e10cSrcweir 			rtl_freeMemory( pTls );
500cdf0e10cSrcweir 			pTls = 0;
501cdf0e10cSrcweir 		}
502cdf0e10cSrcweir 		else
503cdf0e10cSrcweir 			AddKeyToList( pTls );
504cdf0e10cSrcweir 	}
505cdf0e10cSrcweir 
506cdf0e10cSrcweir 	return ((oslThreadKey)pTls);
507cdf0e10cSrcweir }
508cdf0e10cSrcweir 
509cdf0e10cSrcweir /*****************************************************************************/
510cdf0e10cSrcweir /* osl_destroyThreadKey */
511cdf0e10cSrcweir /*****************************************************************************/
osl_destroyThreadKey(oslThreadKey Key)512cdf0e10cSrcweir void SAL_CALL osl_destroyThreadKey(oslThreadKey Key)
513cdf0e10cSrcweir {
514cdf0e10cSrcweir 	if (Key != 0)
515cdf0e10cSrcweir 	{
516cdf0e10cSrcweir 		PTLS	pTls = (PTLS)Key;
517cdf0e10cSrcweir 
518cdf0e10cSrcweir 		RemoveKeyFromList( pTls );
519cdf0e10cSrcweir 		TlsFree( pTls->dwIndex );
520cdf0e10cSrcweir 		rtl_freeMemory( pTls );
521cdf0e10cSrcweir 	}
522cdf0e10cSrcweir }
523cdf0e10cSrcweir 
524cdf0e10cSrcweir /*****************************************************************************/
525cdf0e10cSrcweir /* osl_getThreadKeyData */
526cdf0e10cSrcweir /*****************************************************************************/
osl_getThreadKeyData(oslThreadKey Key)527cdf0e10cSrcweir void* SAL_CALL osl_getThreadKeyData(oslThreadKey Key)
528cdf0e10cSrcweir {
529cdf0e10cSrcweir 	if (Key != 0)
530cdf0e10cSrcweir 	{
531cdf0e10cSrcweir 		PTLS	pTls = (PTLS)Key;
532cdf0e10cSrcweir 
533cdf0e10cSrcweir 		return (TlsGetValue( pTls->dwIndex ));
534cdf0e10cSrcweir 	}
535cdf0e10cSrcweir 
536cdf0e10cSrcweir 	return (NULL);
537cdf0e10cSrcweir }
538cdf0e10cSrcweir 
539cdf0e10cSrcweir /*****************************************************************************/
540cdf0e10cSrcweir /* osl_setThreadKeyData */
541cdf0e10cSrcweir /*****************************************************************************/
osl_setThreadKeyData(oslThreadKey Key,void * pData)542cdf0e10cSrcweir sal_Bool SAL_CALL osl_setThreadKeyData(oslThreadKey Key, void *pData)
543cdf0e10cSrcweir {
544cdf0e10cSrcweir 	if (Key != 0)
545cdf0e10cSrcweir 	{
546cdf0e10cSrcweir 		PTLS	pTls = (PTLS)Key;
547cdf0e10cSrcweir 		void*	pOldData = NULL;
548cdf0e10cSrcweir 		BOOL	fSuccess;
549cdf0e10cSrcweir 
550cdf0e10cSrcweir 		if ( pTls->pfnCallback )
551cdf0e10cSrcweir 			pOldData = TlsGetValue( pTls->dwIndex );
552cdf0e10cSrcweir 
553cdf0e10cSrcweir 		fSuccess = TlsSetValue( pTls->dwIndex, pData );
554cdf0e10cSrcweir 
555cdf0e10cSrcweir 		if ( fSuccess && pTls->pfnCallback && pOldData )
556cdf0e10cSrcweir 			pTls->pfnCallback( pOldData );
557cdf0e10cSrcweir 
558cdf0e10cSrcweir 		return (sal_Bool)(fSuccess != FALSE);
559cdf0e10cSrcweir 	}
560cdf0e10cSrcweir 
561cdf0e10cSrcweir 	return (sal_False);
562cdf0e10cSrcweir }
563cdf0e10cSrcweir 
564cdf0e10cSrcweir 
565cdf0e10cSrcweir /*****************************************************************************/
566cdf0e10cSrcweir /* osl_getThreadTextEncoding */
567cdf0e10cSrcweir /*****************************************************************************/
568cdf0e10cSrcweir 
569cdf0e10cSrcweir DWORD	g_dwTLSTextEncodingIndex = (DWORD)-1;
570cdf0e10cSrcweir 
571cdf0e10cSrcweir 
osl_getThreadTextEncoding(void)572cdf0e10cSrcweir rtl_TextEncoding SAL_CALL osl_getThreadTextEncoding(void)
573cdf0e10cSrcweir {
574cdf0e10cSrcweir 	DWORD				dwEncoding;
575cdf0e10cSrcweir 	rtl_TextEncoding	_encoding;
576cdf0e10cSrcweir 	BOOL				gotACP;
577cdf0e10cSrcweir 
578cdf0e10cSrcweir 	if ( (DWORD)-1 == g_dwTLSTextEncodingIndex )
579cdf0e10cSrcweir 		g_dwTLSTextEncodingIndex = TlsAlloc();
580cdf0e10cSrcweir 
581cdf0e10cSrcweir 	dwEncoding = (DWORD)TlsGetValue( g_dwTLSTextEncodingIndex );
582cdf0e10cSrcweir 	_encoding = LOWORD(dwEncoding);
583cdf0e10cSrcweir 	gotACP = HIWORD(dwEncoding);
584cdf0e10cSrcweir 
585cdf0e10cSrcweir 
586cdf0e10cSrcweir 	if ( !gotACP )
587cdf0e10cSrcweir 	{
588cdf0e10cSrcweir 		char	*pszEncoding;
589cdf0e10cSrcweir 
590cdf0e10cSrcweir 		if ( NULL != (pszEncoding = getenv( "SOLAR_USER_RTL_TEXTENCODING" )) )
591cdf0e10cSrcweir 			_encoding = (rtl_TextEncoding)atoi(pszEncoding);
592cdf0e10cSrcweir 		else
593cdf0e10cSrcweir 			_encoding = rtl_getTextEncodingFromWindowsCodePage( GetACP() );
594cdf0e10cSrcweir 
595cdf0e10cSrcweir 		TlsSetValue( g_dwTLSTextEncodingIndex, (LPVOID)MAKELONG( _encoding, TRUE ) );
596cdf0e10cSrcweir 	}
597cdf0e10cSrcweir 
598cdf0e10cSrcweir 	return _encoding;
599cdf0e10cSrcweir }
600cdf0e10cSrcweir 
601cdf0e10cSrcweir /*****************************************************************************/
602cdf0e10cSrcweir /* osl_getThreadTextEncoding */
603cdf0e10cSrcweir /*****************************************************************************/
osl_setThreadTextEncoding(rtl_TextEncoding Encoding)604cdf0e10cSrcweir rtl_TextEncoding SAL_CALL osl_setThreadTextEncoding( rtl_TextEncoding Encoding )
605cdf0e10cSrcweir {
606cdf0e10cSrcweir 	rtl_TextEncoding oldEncoding = osl_getThreadTextEncoding();
607cdf0e10cSrcweir 
608cdf0e10cSrcweir 	TlsSetValue( g_dwTLSTextEncodingIndex, (LPVOID)MAKELONG( Encoding, TRUE) );
609cdf0e10cSrcweir 
610cdf0e10cSrcweir 	return oldEncoding;
611cdf0e10cSrcweir }
612cdf0e10cSrcweir 
613cdf0e10cSrcweir 
614cdf0e10cSrcweir 
615