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 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 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 549 void SAL_CALL osl_yieldThread() 550 { 551 DosSleep(0); 552 } 553 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 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 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 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 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 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 /*****************************************************************************/ 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