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