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