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