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