xref: /AOO41X/main/sal/osl/os2/thread.c (revision fe22d2cfc602815794415026f1317bd625db6f83)
1647f063dSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3647f063dSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4647f063dSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5647f063dSAndrew Rist  * distributed with this work for additional information
6647f063dSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7647f063dSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8647f063dSAndrew Rist  * "License"); you may not use this file except in compliance
9647f063dSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11647f063dSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13647f063dSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14647f063dSAndrew Rist  * software distributed under the License is distributed on an
15647f063dSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16647f063dSAndrew Rist  * KIND, either express or implied.  See the License for the
17647f063dSAndrew Rist  * specific language governing permissions and limitations
18647f063dSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20647f063dSAndrew Rist  *************************************************************/
21647f063dSAndrew Rist 
22647f063dSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir 
25cdf0e10cSrcweir #include "system.h"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <osl/diagnose.h>
28cdf0e10cSrcweir #include <osl/thread.h>
29cdf0e10cSrcweir #include <osl/time.h>
30cdf0e10cSrcweir #include <rtl/alloc.h>
31cdf0e10cSrcweir #include <rtl/tencinfo.h>
32cdf0e10cSrcweir 
33*c99cd5fcSYuri Dario #define INCL_DOSPROCESS
34*c99cd5fcSYuri Dario #define INCL_DOSEXCEPTIONS
35*c99cd5fcSYuri Dario #define INCL_DOSMODULEMGR
36*c99cd5fcSYuri Dario #include <os2.h>
37*c99cd5fcSYuri Dario #define INCL_LOADEXCEPTQ
38*c99cd5fcSYuri Dario #include <exceptq.h>
39*c99cd5fcSYuri Dario 
40cdf0e10cSrcweir /*
41cdf0e10cSrcweir     Thread-data structure hidden behind oslThread:
42cdf0e10cSrcweir */
43cdf0e10cSrcweir typedef struct _osl_TThreadImpl
44cdf0e10cSrcweir {
45cdf0e10cSrcweir 
46cdf0e10cSrcweir     TID                  m_ThreadId;        /* identifier for this thread */
47cdf0e10cSrcweir     sal_Int32            m_Flags;
48cdf0e10cSrcweir     HEV                  m_hEvent;
49cdf0e10cSrcweir     sal_uInt32           m_Timeout;
50cdf0e10cSrcweir     oslWorkerFunction    m_WorkerFunction;
51cdf0e10cSrcweir     void*                m_pData;
52cdf0e10cSrcweir     sal_Bool             m_StartSuspended;
53cdf0e10cSrcweir     HAB                  m_hab;
54cdf0e10cSrcweir     HMQ                  m_hmq;
55cdf0e10cSrcweir 
56cdf0e10cSrcweir } osl_TThreadImpl;
57cdf0e10cSrcweir 
58cdf0e10cSrcweir #define THREADIMPL_FLAGS_TERMINATE    0x0001
59cdf0e10cSrcweir #define THREADIMPL_FLAGS_SLEEP        0x0002
60cdf0e10cSrcweir 
61cdf0e10cSrcweir 
62cdf0e10cSrcweir // static mutex to control access to private members of oslMutexImpl
63cdf0e10cSrcweir static HMTX MutexLock = NULL;
64cdf0e10cSrcweir 
65cdf0e10cSrcweir /*****************************************************************************/
66cdf0e10cSrcweir 
osl_getPMinternal_HAB(oslThread hThread)67cdf0e10cSrcweir HAB osl_getPMinternal_HAB(oslThread hThread)
68cdf0e10cSrcweir {
69cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)hThread;
70cdf0e10cSrcweir 
71cdf0e10cSrcweir     if(pThreadImpl == NULL) /* valid ptr? */
72cdf0e10cSrcweir     {
73cdf0e10cSrcweir         return NULL;
74cdf0e10cSrcweir     }
75cdf0e10cSrcweir     else
76cdf0e10cSrcweir     {
77cdf0e10cSrcweir         return pThreadImpl->m_hab;
78cdf0e10cSrcweir     }
79cdf0e10cSrcweir }
80cdf0e10cSrcweir 
osl_getPMinternal_HMQ(oslThread hThread)81cdf0e10cSrcweir HMQ osl_getPMinternal_HMQ(oslThread hThread)
82cdf0e10cSrcweir {
83cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)hThread;
84cdf0e10cSrcweir 
85cdf0e10cSrcweir     if(pThreadImpl == NULL) /* valid ptr? */
86cdf0e10cSrcweir     {
87cdf0e10cSrcweir         return NULL;
88cdf0e10cSrcweir     }
89cdf0e10cSrcweir     else
90cdf0e10cSrcweir     {
91cdf0e10cSrcweir         return pThreadImpl->m_hmq;
92cdf0e10cSrcweir     }
93cdf0e10cSrcweir }
94cdf0e10cSrcweir 
95cdf0e10cSrcweir 
96cdf0e10cSrcweir /*****************************************************************************/
97cdf0e10cSrcweir /* oslWorkerWrapperFunction */
98cdf0e10cSrcweir /*****************************************************************************/
oslWorkerWrapperFunction(void * pData)99cdf0e10cSrcweir static void oslWorkerWrapperFunction(void* pData)
100cdf0e10cSrcweir {
101cdf0e10cSrcweir     BOOL rc;
102cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)pData;
103*c99cd5fcSYuri Dario     EXCEPTIONREGISTRATIONRECORD exRegRec = {0};
104*c99cd5fcSYuri Dario     LoadExceptq(&exRegRec, NULL, NULL);
105cdf0e10cSrcweir 
106cdf0e10cSrcweir #if OSL_DEBUG_LEVEL>0
107cdf0e10cSrcweir printf("oslWorkerWrapperFunction pThreadImpl %x, pThreadImpl->m_ThreadId %d\n", pThreadImpl, pThreadImpl->m_ThreadId);
108cdf0e10cSrcweir #endif
109cdf0e10cSrcweir     /* Inizialize PM for this thread */
110cdf0e10cSrcweir     pThreadImpl->m_hab = WinInitialize( 0 );
111cdf0e10cSrcweir #if OSL_DEBUG_LEVEL>0
112cdf0e10cSrcweir printf("pThreadImpl->m_ThreadId %d, pThreadImpl->m_hab %x\n", pThreadImpl->m_ThreadId,pThreadImpl->m_hab);
113cdf0e10cSrcweir #endif
114cdf0e10cSrcweir     pThreadImpl->m_hmq = WinCreateMsgQueue( pThreadImpl->m_hab, 0 );
115cdf0e10cSrcweir #if OSL_DEBUG_LEVEL>0
116cdf0e10cSrcweir printf("pThreadImpl->m_ThreadId %d, pThreadImpl->m_hmq %x\n", pThreadImpl->m_ThreadId,pThreadImpl->m_hmq);
117cdf0e10cSrcweir #endif
118cdf0e10cSrcweir 
119cdf0e10cSrcweir     /* call worker-function with data */
120cdf0e10cSrcweir     pThreadImpl->m_WorkerFunction( pThreadImpl->m_pData );
121cdf0e10cSrcweir 
122cdf0e10cSrcweir 	/* Free all PM-resources for this thread */
123cdf0e10cSrcweir #if OSL_DEBUG_LEVEL>0
124cdf0e10cSrcweir printf("pThreadImpl->m_ThreadId %d, about to destroy queue\n", pThreadImpl->m_ThreadId);
125cdf0e10cSrcweir #endif
126cdf0e10cSrcweir     rc = WinDestroyMsgQueue( pThreadImpl->m_hmq );
127cdf0e10cSrcweir #if OSL_DEBUG_LEVEL>0
128cdf0e10cSrcweir printf("pThreadImpl->m_ThreadId %d, WinDestroyMsgQueue rc=%d (should be 1)\n", pThreadImpl->m_ThreadId, rc);
129cdf0e10cSrcweir printf("pThreadImpl->m_ThreadId %d, about to terminate hab\n", pThreadImpl->m_ThreadId);
130cdf0e10cSrcweir #endif
131cdf0e10cSrcweir     rc = WinTerminate( pThreadImpl->m_hab );
132cdf0e10cSrcweir #if OSL_DEBUG_LEVEL>0
133cdf0e10cSrcweir printf("pThreadImpl->m_ThreadId %d, WinTerminate rc=%d (should be 1)\n", pThreadImpl->m_ThreadId, rc);
134*c99cd5fcSYuri Dario 
135*c99cd5fcSYuri Dario     UninstallExceptq(&exRegRec);
136*c99cd5fcSYuri Dario 
137cdf0e10cSrcweir #endif
138cdf0e10cSrcweir }
139cdf0e10cSrcweir 
140cdf0e10cSrcweir 
141cdf0e10cSrcweir /*****************************************************************************/
142cdf0e10cSrcweir /* oslCreateThread */
143cdf0e10cSrcweir /*****************************************************************************/
oslCreateThread(oslWorkerFunction pWorker,void * pThreadData,sal_Bool nFlags)144cdf0e10cSrcweir static oslThread oslCreateThread(oslWorkerFunction pWorker,
145cdf0e10cSrcweir                                  void* pThreadData,
146cdf0e10cSrcweir                                  sal_Bool nFlags)
147cdf0e10cSrcweir {
148cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl;
149cdf0e10cSrcweir 
150cdf0e10cSrcweir     /* alloc mem. for our internal data structure */
151cdf0e10cSrcweir     pThreadImpl = (osl_TThreadImpl*)malloc(sizeof(osl_TThreadImpl));
152cdf0e10cSrcweir 
153cdf0e10cSrcweir     OSL_ASSERT(pThreadImpl);
154cdf0e10cSrcweir 
155cdf0e10cSrcweir     pThreadImpl->m_WorkerFunction= pWorker;
156cdf0e10cSrcweir     pThreadImpl->m_pData= pThreadData;
157cdf0e10cSrcweir 
158cdf0e10cSrcweir     pThreadImpl->m_Flags   = 0;
159cdf0e10cSrcweir     pThreadImpl->m_hEvent  = 0;
160cdf0e10cSrcweir     pThreadImpl->m_Timeout = 0;
161cdf0e10cSrcweir     pThreadImpl->m_StartSuspended = nFlags;
162cdf0e10cSrcweir     pThreadImpl->m_hab = 0;
163cdf0e10cSrcweir     pThreadImpl->m_hmq = 0;
164cdf0e10cSrcweir 
165cdf0e10cSrcweir     if ( nFlags == sal_True )
166cdf0e10cSrcweir     {
167cdf0e10cSrcweir 		DosRequestMutexSem( MutexLock, SEM_INDEFINITE_WAIT );
168cdf0e10cSrcweir     }
169cdf0e10cSrcweir 
170cdf0e10cSrcweir     pThreadImpl->m_ThreadId = (TID) _beginthread( oslWorkerWrapperFunction,    /* worker-function */
171cdf0e10cSrcweir                                                   NULL,                        /* unused parameter */
172cdf0e10cSrcweir                                                   1024*1024,                   /* max. Stacksize */
173cdf0e10cSrcweir                                                   pThreadImpl );
174cdf0e10cSrcweir     if ( nFlags == sal_True )
175cdf0e10cSrcweir     {
176cdf0e10cSrcweir         if( pThreadImpl->m_ThreadId != -1 )
177cdf0e10cSrcweir             DosSuspendThread( pThreadImpl->m_ThreadId );
178cdf0e10cSrcweir 		DosReleaseMutexSem( MutexLock);
179cdf0e10cSrcweir     }
180cdf0e10cSrcweir #if OSL_DEBUG_LEVEL>0
181cdf0e10cSrcweir printf("oslCreateThread pThreadImpl %x, pThreadImpl->m_ThreadId %d\n", pThreadImpl, pThreadImpl->m_ThreadId);
182cdf0e10cSrcweir #endif
183cdf0e10cSrcweir     if(pThreadImpl->m_ThreadId == -1)
184cdf0e10cSrcweir     {
185cdf0e10cSrcweir         /* create failed */
186cdf0e10cSrcweir         if (pThreadImpl->m_hEvent != 0)
187cdf0e10cSrcweir             DosCloseEventSem(pThreadImpl->m_hEvent);
188cdf0e10cSrcweir 
189cdf0e10cSrcweir         free(pThreadImpl);
190cdf0e10cSrcweir         return 0;
191cdf0e10cSrcweir     }
192cdf0e10cSrcweir 
193cdf0e10cSrcweir     pThreadImpl->m_hEvent= 0;
194cdf0e10cSrcweir 
195cdf0e10cSrcweir     return pThreadImpl;
196cdf0e10cSrcweir 
197cdf0e10cSrcweir }
198cdf0e10cSrcweir 
199cdf0e10cSrcweir /*****************************************************************************/
200cdf0e10cSrcweir /* osl_createThread */
201cdf0e10cSrcweir /*****************************************************************************/
osl_createThread(oslWorkerFunction pWorker,void * pThreadData)202cdf0e10cSrcweir oslThread SAL_CALL osl_createThread(oslWorkerFunction pWorker,
203cdf0e10cSrcweir                                  void* pThreadData)
204cdf0e10cSrcweir {
205cdf0e10cSrcweir     return oslCreateThread(pWorker,pThreadData,sal_False);
206cdf0e10cSrcweir }
207cdf0e10cSrcweir 
208cdf0e10cSrcweir /*****************************************************************************/
209cdf0e10cSrcweir /* osl_createSuspendedThread */
210cdf0e10cSrcweir /*****************************************************************************/
osl_createSuspendedThread(oslWorkerFunction pWorker,void * pThreadData)211cdf0e10cSrcweir oslThread SAL_CALL osl_createSuspendedThread(oslWorkerFunction pWorker,
212cdf0e10cSrcweir                                           void* pThreadData)
213cdf0e10cSrcweir {
214cdf0e10cSrcweir     return oslCreateThread(pWorker,pThreadData,sal_True);
215cdf0e10cSrcweir }
216cdf0e10cSrcweir 
217cdf0e10cSrcweir /*****************************************************************************/
218cdf0e10cSrcweir /* osl_getThreadIdentifier */
219cdf0e10cSrcweir /*****************************************************************************/
osl_getThreadIdentifier(oslThread Thread)220cdf0e10cSrcweir oslThreadIdentifier SAL_CALL osl_getThreadIdentifier(oslThread Thread)
221cdf0e10cSrcweir {
222cdf0e10cSrcweir 	osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
223cdf0e10cSrcweir 
224cdf0e10cSrcweir 	if (pThreadImpl != NULL)
225cdf0e10cSrcweir 		return ((oslThreadIdentifier)pThreadImpl->m_ThreadId);
226cdf0e10cSrcweir 	else
227cdf0e10cSrcweir         {
228cdf0e10cSrcweir         PTIB pptib = NULL;
229cdf0e10cSrcweir         PPIB pppib = NULL;
230cdf0e10cSrcweir 
231cdf0e10cSrcweir         DosGetInfoBlocks( &pptib, &pppib );
232cdf0e10cSrcweir         return ((oslThreadIdentifier) pptib->tib_ptib2->tib2_ultid );
233cdf0e10cSrcweir         }
234cdf0e10cSrcweir }
235cdf0e10cSrcweir 
236cdf0e10cSrcweir /*****************************************************************************/
237cdf0e10cSrcweir /* osl_destroyThread */
238cdf0e10cSrcweir /*****************************************************************************/
osl_destroyThread(oslThread Thread)239cdf0e10cSrcweir void SAL_CALL osl_destroyThread(oslThread Thread)
240cdf0e10cSrcweir {
241cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
242cdf0e10cSrcweir 
243cdf0e10cSrcweir     if(Thread == 0) /* valid ptr? */
244cdf0e10cSrcweir     {
245cdf0e10cSrcweir         /* thread already destroyed or not created */
246cdf0e10cSrcweir         return;
247cdf0e10cSrcweir     }
248cdf0e10cSrcweir 
249cdf0e10cSrcweir     if(pThreadImpl->m_ThreadId != -1)    /* valid handle ? */
250cdf0e10cSrcweir     {
251cdf0e10cSrcweir         /* cancel thread  */
252cdf0e10cSrcweir         DosKillThread( pThreadImpl->m_ThreadId );
253cdf0e10cSrcweir     }
254cdf0e10cSrcweir }
255cdf0e10cSrcweir 
256cdf0e10cSrcweir /*****************************************************************************/
257cdf0e10cSrcweir /* osl_freeThreadHandle */
258cdf0e10cSrcweir /*****************************************************************************/
osl_freeThreadHandle(oslThread Thread)259cdf0e10cSrcweir void SAL_CALL osl_freeThreadHandle(oslThread Thread)
260cdf0e10cSrcweir {
261cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
262cdf0e10cSrcweir 
263cdf0e10cSrcweir     if(Thread == 0)        /* valid ptr? */
264cdf0e10cSrcweir     {
265cdf0e10cSrcweir         /* thread already destroyed or not created */
266cdf0e10cSrcweir         return;
267cdf0e10cSrcweir     }
268cdf0e10cSrcweir 
269cdf0e10cSrcweir     if (pThreadImpl->m_hEvent != 0)
270cdf0e10cSrcweir         DosCloseEventSem(pThreadImpl->m_hEvent);
271cdf0e10cSrcweir 
272cdf0e10cSrcweir     /* free memory */
273cdf0e10cSrcweir     free(Thread);
274cdf0e10cSrcweir }
275cdf0e10cSrcweir 
276cdf0e10cSrcweir /*****************************************************************************/
277cdf0e10cSrcweir /* osl_resumeThread */
278cdf0e10cSrcweir /*****************************************************************************/
osl_resumeThread(oslThread Thread)279cdf0e10cSrcweir void SAL_CALL osl_resumeThread(oslThread Thread)
280cdf0e10cSrcweir {
281cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
282cdf0e10cSrcweir 
283cdf0e10cSrcweir     OSL_ASSERT(pThreadImpl);        /* valid ptr? */
284cdf0e10cSrcweir 
285cdf0e10cSrcweir     DosResumeThread( pThreadImpl->m_ThreadId );
286cdf0e10cSrcweir }
287cdf0e10cSrcweir 
288cdf0e10cSrcweir /*****************************************************************************/
289cdf0e10cSrcweir /* osl_suspendThread */
290cdf0e10cSrcweir /*****************************************************************************/
osl_suspendThread(oslThread Thread)291cdf0e10cSrcweir void SAL_CALL osl_suspendThread(oslThread Thread)
292cdf0e10cSrcweir {
293cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
294cdf0e10cSrcweir 
295cdf0e10cSrcweir     OSL_ASSERT(pThreadImpl);        /* valid ptr? */
296cdf0e10cSrcweir 
297cdf0e10cSrcweir     DosSuspendThread( pThreadImpl->m_ThreadId );
298cdf0e10cSrcweir }
299cdf0e10cSrcweir 
300cdf0e10cSrcweir /*****************************************************************************/
301cdf0e10cSrcweir /* osl_setThreadPriority */
302cdf0e10cSrcweir /*****************************************************************************/
osl_setThreadPriority(oslThread Thread,oslThreadPriority Priority)303cdf0e10cSrcweir void SAL_CALL osl_setThreadPriority(oslThread Thread,
304cdf0e10cSrcweir                            oslThreadPriority Priority)
305cdf0e10cSrcweir {
306cdf0e10cSrcweir     ULONG nOs2PriorityClass;
307cdf0e10cSrcweir     ULONG nOs2PriorityDelta;
308cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
309cdf0e10cSrcweir 
310cdf0e10cSrcweir     OSL_ASSERT(pThreadImpl);        /* valid ptr? */
311cdf0e10cSrcweir 
312cdf0e10cSrcweir     switch(Priority) {
313cdf0e10cSrcweir 
314cdf0e10cSrcweir     case osl_Thread_PriorityHighest:
315cdf0e10cSrcweir 
316cdf0e10cSrcweir         nOs2PriorityClass = PRTYC_REGULAR;
317cdf0e10cSrcweir         nOs2PriorityDelta = PRTYD_MAXIMUM;
318cdf0e10cSrcweir         break;
319cdf0e10cSrcweir 
320cdf0e10cSrcweir     case osl_Thread_PriorityAboveNormal:
321cdf0e10cSrcweir 
322cdf0e10cSrcweir         nOs2PriorityClass = PRTYC_REGULAR;
323cdf0e10cSrcweir         nOs2PriorityDelta = 16;
324cdf0e10cSrcweir         break;
325cdf0e10cSrcweir 
326cdf0e10cSrcweir     case osl_Thread_PriorityNormal:
327cdf0e10cSrcweir 
328cdf0e10cSrcweir         nOs2PriorityClass = PRTYC_REGULAR;
329cdf0e10cSrcweir         nOs2PriorityDelta = 0;
330cdf0e10cSrcweir         break;
331cdf0e10cSrcweir 
332cdf0e10cSrcweir     case osl_Thread_PriorityBelowNormal:
333cdf0e10cSrcweir 
334cdf0e10cSrcweir         nOs2PriorityClass = PRTYC_REGULAR;
335cdf0e10cSrcweir         nOs2PriorityDelta = -16;
336cdf0e10cSrcweir         break;
337cdf0e10cSrcweir 
338cdf0e10cSrcweir     case osl_Thread_PriorityLowest:
339cdf0e10cSrcweir 
340cdf0e10cSrcweir         nOs2PriorityClass = PRTYC_REGULAR;
341cdf0e10cSrcweir         nOs2PriorityDelta = PRTYD_MINIMUM;
342cdf0e10cSrcweir         break;
343cdf0e10cSrcweir 
344cdf0e10cSrcweir     case osl_Thread_PriorityUnknown:
345cdf0e10cSrcweir         OSL_ASSERT(FALSE);        /* only fools try this...*/
346cdf0e10cSrcweir 
347cdf0e10cSrcweir         /* let release-version behave friendly */
348cdf0e10cSrcweir         return;
349cdf0e10cSrcweir 
350cdf0e10cSrcweir     default:
351cdf0e10cSrcweir         OSL_ASSERT(FALSE);        /* enum expanded, but forgotten here...*/
352cdf0e10cSrcweir 
353cdf0e10cSrcweir         /* let release-version behave friendly */
354cdf0e10cSrcweir         return;
355cdf0e10cSrcweir     }
356cdf0e10cSrcweir 
357cdf0e10cSrcweir     DosSetPriority( PRTYS_THREAD,
358cdf0e10cSrcweir                     nOs2PriorityClass, nOs2PriorityDelta,
359cdf0e10cSrcweir                     pThreadImpl->m_ThreadId );
360cdf0e10cSrcweir 
361cdf0e10cSrcweir }
362cdf0e10cSrcweir 
363cdf0e10cSrcweir /*****************************************************************************/
364cdf0e10cSrcweir /* osl_getThreadPriority  */
365cdf0e10cSrcweir /*****************************************************************************/
366cdf0e10cSrcweir 
367cdf0e10cSrcweir #define BYTE1FROMULONG(ul) ((UCHAR) (ul))
368cdf0e10cSrcweir #define BYTE2FROMULONG(ul) ((UCHAR) ((ULONG) ul >> 8))
369cdf0e10cSrcweir 
osl_getThreadPriority(const oslThread Thread)370cdf0e10cSrcweir oslThreadPriority  SAL_CALL osl_getThreadPriority(const oslThread Thread)
371cdf0e10cSrcweir {
372cdf0e10cSrcweir     ULONG nOs2PriorityClass;
373cdf0e10cSrcweir     ULONG nOs2PriorityDelta;
374cdf0e10cSrcweir 
375cdf0e10cSrcweir     oslThreadPriority Priority;
376cdf0e10cSrcweir 
377cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
378cdf0e10cSrcweir 
379cdf0e10cSrcweir     /* invalid arguments ?*/
380cdf0e10cSrcweir     if(pThreadImpl==0 || pThreadImpl->m_ThreadId==-1)
381cdf0e10cSrcweir     {
382cdf0e10cSrcweir         return osl_Thread_PriorityUnknown;
383cdf0e10cSrcweir     }
384cdf0e10cSrcweir 
385cdf0e10cSrcweir     /* get current priorities */
386cdf0e10cSrcweir     {
387cdf0e10cSrcweir     PTIB pptib = NULL;
388cdf0e10cSrcweir     PPIB pppib = NULL;
389cdf0e10cSrcweir 
390cdf0e10cSrcweir     DosGetInfoBlocks( &pptib, &pppib );
391cdf0e10cSrcweir     nOs2PriorityClass = BYTE1FROMULONG( pptib->tib_ptib2->tib2_ulpri );
392cdf0e10cSrcweir     nOs2PriorityDelta = BYTE2FROMULONG( pptib->tib_ptib2->tib2_ulpri );
393cdf0e10cSrcweir     }
394cdf0e10cSrcweir 
395cdf0e10cSrcweir     /* map OS2 priority to enum */
396cdf0e10cSrcweir     switch(nOs2PriorityClass)
397cdf0e10cSrcweir     {
398cdf0e10cSrcweir     case PRTYC_TIMECRITICAL:
399cdf0e10cSrcweir         Priority= osl_Thread_PriorityHighest;
400cdf0e10cSrcweir         break;
401cdf0e10cSrcweir 
402cdf0e10cSrcweir     case PRTYC_REGULAR:
403cdf0e10cSrcweir 
404cdf0e10cSrcweir         if( nOs2PriorityDelta == 0 )
405cdf0e10cSrcweir         {
406cdf0e10cSrcweir             Priority= osl_Thread_PriorityNormal;
407cdf0e10cSrcweir             break;
408cdf0e10cSrcweir         }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir         if( nOs2PriorityDelta < -16 )
411cdf0e10cSrcweir         {
412cdf0e10cSrcweir             Priority= osl_Thread_PriorityLowest;
413cdf0e10cSrcweir             break;
414cdf0e10cSrcweir         }
415cdf0e10cSrcweir 
416cdf0e10cSrcweir         if( nOs2PriorityDelta < 0 )
417cdf0e10cSrcweir         {
418cdf0e10cSrcweir             Priority= osl_Thread_PriorityBelowNormal;
419cdf0e10cSrcweir             break;
420cdf0e10cSrcweir         }
421cdf0e10cSrcweir 
422cdf0e10cSrcweir         if( nOs2PriorityDelta > 0 )
423cdf0e10cSrcweir         {
424cdf0e10cSrcweir             Priority= osl_Thread_PriorityAboveNormal;
425cdf0e10cSrcweir             break;
426cdf0e10cSrcweir         }
427cdf0e10cSrcweir 
428cdf0e10cSrcweir         Priority= osl_Thread_PriorityHighest;
429cdf0e10cSrcweir         break;
430cdf0e10cSrcweir 
431cdf0e10cSrcweir     case PRTYC_IDLETIME:
432cdf0e10cSrcweir         Priority= osl_Thread_PriorityLowest;
433cdf0e10cSrcweir         break;
434cdf0e10cSrcweir 
435cdf0e10cSrcweir     default:
436cdf0e10cSrcweir         OSL_ASSERT(FALSE);        /* OS/2 API changed, incorporate new prio-level! */
437cdf0e10cSrcweir 
438cdf0e10cSrcweir         /* release-version behaves friendly */
439cdf0e10cSrcweir         Priority= osl_Thread_PriorityUnknown;
440cdf0e10cSrcweir     }
441cdf0e10cSrcweir 
442cdf0e10cSrcweir     return Priority;
443cdf0e10cSrcweir }
444cdf0e10cSrcweir 
445cdf0e10cSrcweir /*****************************************************************************/
446cdf0e10cSrcweir /* osl_isThreadRunning */
447cdf0e10cSrcweir /*****************************************************************************/
osl_isThreadRunning(const oslThread Thread)448cdf0e10cSrcweir sal_Bool SAL_CALL osl_isThreadRunning(const oslThread Thread)
449cdf0e10cSrcweir {
450cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
451cdf0e10cSrcweir     APIRET rc;
452cdf0e10cSrcweir 
453cdf0e10cSrcweir     /* invalid arguments ?*/
454cdf0e10cSrcweir     if(pThreadImpl==0 || pThreadImpl->m_ThreadId==-1)
455cdf0e10cSrcweir     {
456cdf0e10cSrcweir         return sal_False;
457cdf0e10cSrcweir     }
458cdf0e10cSrcweir 
459cdf0e10cSrcweir 	if( osl_getThreadIdentifier( 0 ) == osl_getThreadIdentifier( Thread ) )
460cdf0e10cSrcweir 		return sal_True;
461cdf0e10cSrcweir 
462cdf0e10cSrcweir     rc = DosWaitThread( &pThreadImpl->m_ThreadId, DCWW_NOWAIT );
463cdf0e10cSrcweir 
464cdf0e10cSrcweir     return( rc != ERROR_INVALID_THREADID );
465cdf0e10cSrcweir }
466cdf0e10cSrcweir 
467cdf0e10cSrcweir /*****************************************************************************/
468cdf0e10cSrcweir /* osl_joinWithThread */
469cdf0e10cSrcweir /*****************************************************************************/
osl_joinWithThread(oslThread Thread)470cdf0e10cSrcweir void SAL_CALL osl_joinWithThread(oslThread Thread)
471cdf0e10cSrcweir {
472cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
473cdf0e10cSrcweir 
474cdf0e10cSrcweir     /* invalid arguments?*/
475cdf0e10cSrcweir     if(pThreadImpl==0 || pThreadImpl->m_ThreadId==-1)
476cdf0e10cSrcweir     {
477cdf0e10cSrcweir         /* assume thread is not running */
478cdf0e10cSrcweir         return;
479cdf0e10cSrcweir     }
480cdf0e10cSrcweir 
481cdf0e10cSrcweir     DosWaitThread( &pThreadImpl->m_ThreadId, DCWW_WAIT );
482cdf0e10cSrcweir }
483cdf0e10cSrcweir 
484cdf0e10cSrcweir /*****************************************************************************/
485cdf0e10cSrcweir /* osl_waitThread */
486cdf0e10cSrcweir /*****************************************************************************/
osl_waitThread(const TimeValue * pDelay)487cdf0e10cSrcweir void SAL_CALL osl_waitThread(const TimeValue* pDelay)
488cdf0e10cSrcweir {
489cdf0e10cSrcweir     int millisecs;
490cdf0e10cSrcweir 
491cdf0e10cSrcweir     OSL_ASSERT(pDelay);
492cdf0e10cSrcweir 
493cdf0e10cSrcweir     millisecs = pDelay->Seconds * 1000 + pDelay->Nanosec / 1000000;
494cdf0e10cSrcweir 
495cdf0e10cSrcweir     DosSleep(millisecs);
496cdf0e10cSrcweir }
497cdf0e10cSrcweir 
498cdf0e10cSrcweir /*****************************************************************************/
499cdf0e10cSrcweir /* osl_terminateThread */
500cdf0e10cSrcweir /*****************************************************************************/
osl_terminateThread(oslThread Thread)501cdf0e10cSrcweir void SAL_CALL osl_terminateThread(oslThread Thread)
502cdf0e10cSrcweir {
503cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
504cdf0e10cSrcweir 
505cdf0e10cSrcweir     /* invalid arguments?*/
506cdf0e10cSrcweir     if (pThreadImpl==0 || pThreadImpl->m_ThreadId==-1)
507cdf0e10cSrcweir     {
508cdf0e10cSrcweir         /* assume thread is not running */
509cdf0e10cSrcweir         return;
510cdf0e10cSrcweir     }
511cdf0e10cSrcweir 
512cdf0e10cSrcweir     DosRequestMutexSem( MutexLock, SEM_INDEFINITE_WAIT );
513cdf0e10cSrcweir     pThreadImpl->m_Flags |= THREADIMPL_FLAGS_TERMINATE;
514cdf0e10cSrcweir     DosReleaseMutexSem( MutexLock);
515cdf0e10cSrcweir }
516cdf0e10cSrcweir 
517cdf0e10cSrcweir 
518cdf0e10cSrcweir /*****************************************************************************/
519cdf0e10cSrcweir /* osl_scheduleThread */
520cdf0e10cSrcweir /*****************************************************************************/
osl_scheduleThread(oslThread Thread)521cdf0e10cSrcweir sal_Bool SAL_CALL osl_scheduleThread(oslThread Thread)
522cdf0e10cSrcweir {
523cdf0e10cSrcweir     osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread;
524cdf0e10cSrcweir 
525cdf0e10cSrcweir     osl_yieldThread();
526cdf0e10cSrcweir 
527cdf0e10cSrcweir     /* invalid arguments?*/
528cdf0e10cSrcweir     if (pThreadImpl==0 || pThreadImpl->m_ThreadId==-1)
529cdf0e10cSrcweir     {
530cdf0e10cSrcweir         /* assume thread is not running */
531cdf0e10cSrcweir         return sal_False;
532cdf0e10cSrcweir     }
533cdf0e10cSrcweir 
534cdf0e10cSrcweir     if (pThreadImpl->m_Flags & THREADIMPL_FLAGS_SLEEP)
535cdf0e10cSrcweir     {
536cdf0e10cSrcweir         OSL_ASSERT (pThreadImpl->m_hEvent != 0);
537cdf0e10cSrcweir 
538cdf0e10cSrcweir         DosWaitEventSem(pThreadImpl->m_hEvent, pThreadImpl->m_Timeout);
539cdf0e10cSrcweir 
540cdf0e10cSrcweir 		DosRequestMutexSem( MutexLock, SEM_INDEFINITE_WAIT );
541cdf0e10cSrcweir 
542cdf0e10cSrcweir         pThreadImpl->m_Timeout = 0;
543cdf0e10cSrcweir 
544cdf0e10cSrcweir         pThreadImpl->m_Flags &= ~THREADIMPL_FLAGS_SLEEP;
545cdf0e10cSrcweir 
546cdf0e10cSrcweir 		DosReleaseMutexSem( MutexLock);
547cdf0e10cSrcweir     }
548cdf0e10cSrcweir 
549cdf0e10cSrcweir     return ((pThreadImpl->m_Flags & THREADIMPL_FLAGS_TERMINATE) == 0);
550cdf0e10cSrcweir }
551cdf0e10cSrcweir 
552cdf0e10cSrcweir /*****************************************************************************/
553cdf0e10cSrcweir /* osl_yieldThread */
554cdf0e10cSrcweir /*****************************************************************************/
osl_yieldThread()555cdf0e10cSrcweir void SAL_CALL osl_yieldThread()
556cdf0e10cSrcweir {
557cdf0e10cSrcweir     DosSleep(0);
558cdf0e10cSrcweir }
559cdf0e10cSrcweir 
osl_setThreadName(char const * name)560cdf0e10cSrcweir void osl_setThreadName(char const * name) {
561cdf0e10cSrcweir     (void) name;
562cdf0e10cSrcweir }
563cdf0e10cSrcweir 
564cdf0e10cSrcweir typedef struct _TLS
565cdf0e10cSrcweir {
566cdf0e10cSrcweir 	PULONG							pulPtr;
567cdf0e10cSrcweir 	oslThreadKeyCallbackFunction	pfnCallback;
568cdf0e10cSrcweir 	struct _TLS						*pNext, *pPrev;
569cdf0e10cSrcweir } TLS, *PTLS;
570cdf0e10cSrcweir 
571cdf0e10cSrcweir static	PTLS		g_pThreadKeyList = NULL;
572cdf0e10cSrcweir 
AddKeyToList(PTLS pTls)573cdf0e10cSrcweir static void AddKeyToList( PTLS pTls )
574cdf0e10cSrcweir {
575cdf0e10cSrcweir 	if ( pTls )
576cdf0e10cSrcweir 	{
577cdf0e10cSrcweir 		DosRequestMutexSem( MutexLock, SEM_INDEFINITE_WAIT );
578cdf0e10cSrcweir 
579cdf0e10cSrcweir 		pTls->pNext = g_pThreadKeyList;
580cdf0e10cSrcweir 		pTls->pPrev = 0;
581cdf0e10cSrcweir 
582cdf0e10cSrcweir 		if ( g_pThreadKeyList )
583cdf0e10cSrcweir 			g_pThreadKeyList->pPrev = pTls;
584cdf0e10cSrcweir 
585cdf0e10cSrcweir 		g_pThreadKeyList = pTls;
586cdf0e10cSrcweir 
587cdf0e10cSrcweir 		DosReleaseMutexSem( MutexLock);
588cdf0e10cSrcweir 	}
589cdf0e10cSrcweir }
590cdf0e10cSrcweir 
RemoveKeyFromList(PTLS pTls)591cdf0e10cSrcweir static void RemoveKeyFromList( PTLS pTls )
592cdf0e10cSrcweir {
593cdf0e10cSrcweir 	if ( pTls )
594cdf0e10cSrcweir 	{
595cdf0e10cSrcweir 		DosRequestMutexSem( MutexLock, SEM_INDEFINITE_WAIT );
596cdf0e10cSrcweir 		if ( pTls->pPrev )
597cdf0e10cSrcweir 			pTls->pPrev->pNext = pTls->pNext;
598cdf0e10cSrcweir 		else
599cdf0e10cSrcweir 		{
600cdf0e10cSrcweir 			OSL_ASSERT( pTls == g_pThreadKeyList );
601cdf0e10cSrcweir 			g_pThreadKeyList = pTls->pNext;
602cdf0e10cSrcweir 		}
603cdf0e10cSrcweir 
604cdf0e10cSrcweir 		if ( pTls->pNext )
605cdf0e10cSrcweir 			pTls->pNext->pPrev = pTls->pPrev;
606cdf0e10cSrcweir 		DosReleaseMutexSem( MutexLock);
607cdf0e10cSrcweir 	}
608cdf0e10cSrcweir }
609cdf0e10cSrcweir 
_osl_callThreadKeyCallbackOnThreadDetach(void)610cdf0e10cSrcweir void SAL_CALL _osl_callThreadKeyCallbackOnThreadDetach(void)
611cdf0e10cSrcweir {
612cdf0e10cSrcweir 	PTLS	pTls;
613cdf0e10cSrcweir 
614cdf0e10cSrcweir     DosRequestMutexSem( MutexLock, SEM_INDEFINITE_WAIT );
615cdf0e10cSrcweir 	pTls = g_pThreadKeyList;
616cdf0e10cSrcweir 	while ( pTls )
617cdf0e10cSrcweir 	{
618cdf0e10cSrcweir 		if ( pTls->pfnCallback )
619cdf0e10cSrcweir 		{
620cdf0e10cSrcweir 			void	*pValue	= (void*)*pTls->pulPtr;
621cdf0e10cSrcweir 
622cdf0e10cSrcweir 			if ( pValue )
623cdf0e10cSrcweir 				pTls->pfnCallback( pValue );
624cdf0e10cSrcweir 		}
625cdf0e10cSrcweir 
626cdf0e10cSrcweir 		pTls = pTls->pNext;
627cdf0e10cSrcweir 	}
628cdf0e10cSrcweir     DosReleaseMutexSem( MutexLock);
629cdf0e10cSrcweir }
630cdf0e10cSrcweir 
631cdf0e10cSrcweir /*****************************************************************************/
632cdf0e10cSrcweir /* osl_createThreadKey */
633cdf0e10cSrcweir /*****************************************************************************/
osl_createThreadKey(oslThreadKeyCallbackFunction pCallback)634cdf0e10cSrcweir oslThreadKey SAL_CALL osl_createThreadKey(oslThreadKeyCallbackFunction pCallback)
635cdf0e10cSrcweir {
636cdf0e10cSrcweir 	PTLS	pTls = (PTLS)rtl_allocateMemory( sizeof(TLS) );
637cdf0e10cSrcweir 
638cdf0e10cSrcweir 	if ( pTls )
639cdf0e10cSrcweir 	{
640cdf0e10cSrcweir 		pTls->pfnCallback = pCallback;
641cdf0e10cSrcweir 		if (DosAllocThreadLocalMemory(1, &pTls->pulPtr) != NO_ERROR)
642cdf0e10cSrcweir 		{
643cdf0e10cSrcweir 			rtl_freeMemory( pTls );
644cdf0e10cSrcweir 			pTls = 0;
645cdf0e10cSrcweir 		}
646cdf0e10cSrcweir 		else
647cdf0e10cSrcweir 		{
648cdf0e10cSrcweir 			*pTls->pulPtr = 0;
649cdf0e10cSrcweir 			AddKeyToList( pTls );
650cdf0e10cSrcweir 		}
651cdf0e10cSrcweir 	}
652cdf0e10cSrcweir 
653cdf0e10cSrcweir 	return ((oslThreadKey)pTls);
654cdf0e10cSrcweir }
655cdf0e10cSrcweir 
656cdf0e10cSrcweir /*****************************************************************************/
657cdf0e10cSrcweir /* osl_destroyThreadKey */
658cdf0e10cSrcweir /*****************************************************************************/
osl_destroyThreadKey(oslThreadKey Key)659cdf0e10cSrcweir void SAL_CALL osl_destroyThreadKey(oslThreadKey Key)
660cdf0e10cSrcweir {
661cdf0e10cSrcweir 	if (Key != 0)
662cdf0e10cSrcweir 	{
663cdf0e10cSrcweir 		PTLS	pTls = (PTLS)Key;
664cdf0e10cSrcweir 
665cdf0e10cSrcweir 		RemoveKeyFromList( pTls );
666cdf0e10cSrcweir 		DosFreeThreadLocalMemory(pTls->pulPtr);
667cdf0e10cSrcweir 		rtl_freeMemory( pTls );
668cdf0e10cSrcweir 	}
669cdf0e10cSrcweir }
670cdf0e10cSrcweir 
671cdf0e10cSrcweir /*****************************************************************************/
672cdf0e10cSrcweir /* osl_getThreadKeyData */
673cdf0e10cSrcweir /*****************************************************************************/
osl_getThreadKeyData(oslThreadKey Key)674cdf0e10cSrcweir void * SAL_CALL osl_getThreadKeyData(oslThreadKey Key)
675cdf0e10cSrcweir {
676cdf0e10cSrcweir 	if (Key != 0)
677cdf0e10cSrcweir 	{
678cdf0e10cSrcweir 		PTLS	pTls = (PTLS)Key;
679cdf0e10cSrcweir 
680cdf0e10cSrcweir 		return ((void *) *pTls->pulPtr);
681cdf0e10cSrcweir 	}
682cdf0e10cSrcweir 
683cdf0e10cSrcweir 	return (NULL);
684cdf0e10cSrcweir }
685cdf0e10cSrcweir 
686cdf0e10cSrcweir /*****************************************************************************/
687cdf0e10cSrcweir /* osl_setThreadKeyData */
688cdf0e10cSrcweir /*****************************************************************************/
osl_setThreadKeyData(oslThreadKey Key,void * pData)689cdf0e10cSrcweir sal_Bool SAL_CALL osl_setThreadKeyData(oslThreadKey Key, void *pData)
690cdf0e10cSrcweir {
691cdf0e10cSrcweir 	if (Key != 0)
692cdf0e10cSrcweir 	{
693cdf0e10cSrcweir 		PTLS	pTls = (PTLS)Key;
694cdf0e10cSrcweir 		void*	pOldData = NULL;
695cdf0e10cSrcweir 		BOOL	fSuccess = TRUE; //YD cannot fail
696cdf0e10cSrcweir 
697cdf0e10cSrcweir 		if ( pTls->pfnCallback )
698cdf0e10cSrcweir 			pOldData = (void*)*pTls->pulPtr;
699cdf0e10cSrcweir 
700cdf0e10cSrcweir 		*pTls->pulPtr = (ULONG)pData;
701cdf0e10cSrcweir 
702cdf0e10cSrcweir 		if ( fSuccess && pTls->pfnCallback && pOldData )
703cdf0e10cSrcweir 			pTls->pfnCallback( pOldData );
704cdf0e10cSrcweir 
705cdf0e10cSrcweir 		return (sal_Bool)(fSuccess != FALSE);
706cdf0e10cSrcweir 	}
707cdf0e10cSrcweir 
708cdf0e10cSrcweir 	return (sal_False);
709cdf0e10cSrcweir }
710cdf0e10cSrcweir 
711cdf0e10cSrcweir 
712cdf0e10cSrcweir 
713cdf0e10cSrcweir /*****************************************************************************/
714cdf0e10cSrcweir /* osl_getThreadTextEncoding */
715cdf0e10cSrcweir /*****************************************************************************/
716cdf0e10cSrcweir 
717cdf0e10cSrcweir ULONG	g_dwTLSTextEncodingIndex = (ULONG)-1;
718cdf0e10cSrcweir 
_GetACP(void)719cdf0e10cSrcweir sal_uInt32 SAL_CALL _GetACP( void)
720cdf0e10cSrcweir {
721cdf0e10cSrcweir 	APIRET	rc;
722cdf0e10cSrcweir 	ULONG  	aulCpList[8]  = {0};
723cdf0e10cSrcweir 	ULONG	ulListSize;
724cdf0e10cSrcweir 
725cdf0e10cSrcweir 	rc = DosQueryCp( sizeof( aulCpList), aulCpList, &ulListSize);
726cdf0e10cSrcweir 	if (rc)
727cdf0e10cSrcweir 		return 437;	// in case of error, return codepage EN_US
728cdf0e10cSrcweir 	// current codepage is first of list, others are the prepared codepages.
729cdf0e10cSrcweir 	return aulCpList[0];
730cdf0e10cSrcweir }
731cdf0e10cSrcweir 
osl_getThreadTextEncoding(void)732cdf0e10cSrcweir rtl_TextEncoding SAL_CALL osl_getThreadTextEncoding(void)
733cdf0e10cSrcweir {
734cdf0e10cSrcweir 	rtl_TextEncoding	_encoding;
735cdf0e10cSrcweir 
736cdf0e10cSrcweir 	if ( (ULONG)-1 == g_dwTLSTextEncodingIndex ) {
737cdf0e10cSrcweir 		rtl_TextEncoding defaultEncoding;
738cdf0e10cSrcweir 		const char *     pszEncoding;
739cdf0e10cSrcweir 
740cdf0e10cSrcweir 		/* create thread specific data key */
741cdf0e10cSrcweir 		g_dwTLSTextEncodingIndex = osl_createThreadKey( NULL);
742cdf0e10cSrcweir 
743cdf0e10cSrcweir 		/* determine default text encoding */
744cdf0e10cSrcweir 		pszEncoding = getenv ("SOLAR_USER_RTL_TEXTENCODING");
745cdf0e10cSrcweir 		if (pszEncoding)
746cdf0e10cSrcweir 			defaultEncoding = atoi(pszEncoding);
747cdf0e10cSrcweir 		else
748cdf0e10cSrcweir 			defaultEncoding = rtl_getTextEncodingFromWindowsCodePage( _GetACP());
749cdf0e10cSrcweir 
750cdf0e10cSrcweir 		//OSL_ASSERT(defaultEncoding != RTL_TEXTENCODING_DONTKNOW);
751cdf0e10cSrcweir 		//g_thread.m_textencoding.m_default = defaultEncoding;
752cdf0e10cSrcweir 		osl_setThreadKeyData( g_dwTLSTextEncodingIndex, (void*)defaultEncoding);
753cdf0e10cSrcweir 	}
754cdf0e10cSrcweir 
755cdf0e10cSrcweir 	_encoding = (rtl_TextEncoding)osl_getThreadKeyData( g_dwTLSTextEncodingIndex );
756cdf0e10cSrcweir 	if (0 == _encoding) {
757cdf0e10cSrcweir 		const char *     pszEncoding;
758cdf0e10cSrcweir 		/* determine default text encoding */
759cdf0e10cSrcweir 		pszEncoding = getenv ("SOLAR_USER_RTL_TEXTENCODING");
760cdf0e10cSrcweir 		if (pszEncoding)
761cdf0e10cSrcweir 			_encoding = atoi(pszEncoding);
762cdf0e10cSrcweir 		else
763cdf0e10cSrcweir 			_encoding = rtl_getTextEncodingFromWindowsCodePage( _GetACP());
764cdf0e10cSrcweir 		/* save for future reference */
765cdf0e10cSrcweir 		osl_setThreadKeyData( g_dwTLSTextEncodingIndex, (void*)_encoding);
766cdf0e10cSrcweir 	}
767cdf0e10cSrcweir 
768cdf0e10cSrcweir 	return _encoding;
769cdf0e10cSrcweir }
770cdf0e10cSrcweir 
771cdf0e10cSrcweir /*****************************************************************************/
772cdf0e10cSrcweir /* osl_getThreadTextEncoding */
773cdf0e10cSrcweir /*****************************************************************************/
osl_setThreadTextEncoding(rtl_TextEncoding Encoding)774cdf0e10cSrcweir rtl_TextEncoding SAL_CALL osl_setThreadTextEncoding( rtl_TextEncoding Encoding )
775cdf0e10cSrcweir {
776cdf0e10cSrcweir 	rtl_TextEncoding oldEncoding = osl_getThreadTextEncoding();
777cdf0e10cSrcweir 
778cdf0e10cSrcweir 	osl_setThreadKeyData( g_dwTLSTextEncodingIndex, (void*)Encoding);
779cdf0e10cSrcweir 
780cdf0e10cSrcweir 	return oldEncoding;
781cdf0e10cSrcweir }
782cdf0e10cSrcweir 
783cdf0e10cSrcweir 
784cdf0e10cSrcweir 
785