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