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 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 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 555 void SAL_CALL osl_yieldThread() 556 { 557 DosSleep(0); 558 } 559 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 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 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 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 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 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 /*****************************************************************************/ 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