diff options
author | Vladimir Glazounov <vg@openoffice.org> | 2007-09-20 14:15:38 +0000 |
---|---|---|
committer | Vladimir Glazounov <vg@openoffice.org> | 2007-09-20 14:15:38 +0000 |
commit | 8be4682b29e49dbe7e8e6df23aed2c372b621010 (patch) | |
tree | 903b5bfd0966aef022cca4e3b6d5cd105042102b /sal/osl/os2/thread.c | |
parent | af212f6f88e78eff765b0c94baf53d4ca3457b89 (diff) |
INTEGRATION: CWS os2port01 (1.3.2); FILE ADDED
2006/11/29 14:26:44 ydario 1.3.2.1: Initial OS/2 import.
Diffstat (limited to 'sal/osl/os2/thread.c')
-rw-r--r-- | sal/osl/os2/thread.c | 907 |
1 files changed, 907 insertions, 0 deletions
diff --git a/sal/osl/os2/thread.c b/sal/osl/os2/thread.c new file mode 100644 index 000000000000..f39261c5d649 --- /dev/null +++ b/sal/osl/os2/thread.c @@ -0,0 +1,907 @@ +/************************************************************************* + * + * $RCSfile: thread.c,v $ + * + * $Revision: 1.4 $ + * + * last change: $Author: vg $ $Date: 2007-09-20 15:15:38 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + + +#include "system.h" + +#include <osl/diagnose.h> +#include <osl/thread.h> +#ifndef _OSL_TIME_H_ +#include <osl/time.h> +#endif +#include <rtl/alloc.h> +#include <rtl/tencinfo.h> + +/* + Thread-data structure hidden behind oslThread: +*/ +typedef struct _osl_TThreadImpl +{ + + TID m_ThreadId; /* identifier for this thread */ + sal_Int32 m_Flags; + HEV m_hEvent; + sal_uInt32 m_Timeout; + oslWorkerFunction m_WorkerFunction; + void* m_pData; + sal_Bool m_StartSuspended; + HAB m_hab; + HMQ m_hmq; + +} osl_TThreadImpl; + +#define THREADIMPL_FLAGS_TERMINATE 0x0001 +#define THREADIMPL_FLAGS_SLEEP 0x0002 + +HAB osl_getPMinternal_HAB(oslThread hThread) +{ + osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)hThread; + + if(pThreadImpl == NULL) /* valid ptr? */ + { + return NULL; + } + else + { + return pThreadImpl->m_hab; + } +} + +HMQ osl_getPMinternal_HMQ(oslThread hThread) +{ + osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)hThread; + + if(pThreadImpl == NULL) /* valid ptr? */ + { + return NULL; + } + else + { + return pThreadImpl->m_hmq; + } +} + + +/*****************************************************************************/ +/* oslWorkerWrapperFunction */ +/*****************************************************************************/ +static void oslWorkerWrapperFunction(void* pData) +{ + BOOL rc; + osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)pData; + +#if OSL_DEBUG_LEVEL>0 +printf("oslWorkerWrapperFunction pThreadImpl %x, pThreadImpl->m_ThreadId %d\n", pThreadImpl, pThreadImpl->m_ThreadId); +#endif + /* Inizialize PM for this thread */ + pThreadImpl->m_hab = WinInitialize( 0 ); +#if OSL_DEBUG_LEVEL>0 +printf("pThreadImpl->m_ThreadId %d, pThreadImpl->m_hab %x\n", pThreadImpl->m_ThreadId,pThreadImpl->m_hab); +#endif + pThreadImpl->m_hmq = WinCreateMsgQueue( pThreadImpl->m_hab, 0 ); +#if OSL_DEBUG_LEVEL>0 +printf("pThreadImpl->m_ThreadId %d, pThreadImpl->m_hmq %x\n", pThreadImpl->m_ThreadId,pThreadImpl->m_hmq); +#endif + + /* call worker-function with data */ + pThreadImpl->m_WorkerFunction( pThreadImpl->m_pData ); + + /* Free all PM-resources for this thread */ +#if OSL_DEBUG_LEVEL>0 +printf("pThreadImpl->m_ThreadId %d, about to destroy queue\n", pThreadImpl->m_ThreadId); +#endif + rc = WinDestroyMsgQueue( pThreadImpl->m_hmq ); +#if OSL_DEBUG_LEVEL>0 +printf("pThreadImpl->m_ThreadId %d, WinDestroyMsgQueue rc=%d (should be 1)\n", pThreadImpl->m_ThreadId, rc); +printf("pThreadImpl->m_ThreadId %d, about to terminate hab\n", pThreadImpl->m_ThreadId); +#endif + rc = WinTerminate( pThreadImpl->m_hab ); +#if OSL_DEBUG_LEVEL>0 +printf("pThreadImpl->m_ThreadId %d, WinTerminate rc=%d (should be 1)\n", pThreadImpl->m_ThreadId, rc); +#endif +} + + +/*****************************************************************************/ +/* oslCreateThread */ +/*****************************************************************************/ +static oslThread oslCreateThread(oslWorkerFunction pWorker, + void* pThreadData, + sal_Bool nFlags) +{ + osl_TThreadImpl* pThreadImpl; + + /* alloc mem. for our internal data structure */ + pThreadImpl = (osl_TThreadImpl*)malloc(sizeof(osl_TThreadImpl)); + + OSL_ASSERT(pThreadImpl); + + pThreadImpl->m_WorkerFunction= pWorker; + pThreadImpl->m_pData= pThreadData; + + pThreadImpl->m_Flags = 0; + pThreadImpl->m_hEvent = 0; + pThreadImpl->m_Timeout = 0; + pThreadImpl->m_StartSuspended = nFlags; + pThreadImpl->m_hab = 0; + pThreadImpl->m_hmq = 0; + + if ( nFlags == sal_True ) + { + DosEnterCritSec(); + } + + pThreadImpl->m_ThreadId = (TID) _beginthread( oslWorkerWrapperFunction, /* worker-function */ + NULL, /* unused parameter */ + 1024*1024, /* max. Stacksize */ + pThreadImpl ); + if ( nFlags == sal_True ) + { + if( pThreadImpl->m_ThreadId != -1 ) + DosSuspendThread( pThreadImpl->m_ThreadId ); + DosExitCritSec(); + } +#if OSL_DEBUG_LEVEL>0 +printf("oslCreateThread pThreadImpl %x, pThreadImpl->m_ThreadId %d\n", pThreadImpl, pThreadImpl->m_ThreadId); +#endif + if(pThreadImpl->m_ThreadId == -1) + { + /* create failed */ + if (pThreadImpl->m_hEvent != 0) + DosCloseEventSem(pThreadImpl->m_hEvent); + + free(pThreadImpl); + return 0; + } + + pThreadImpl->m_hEvent= 0; + + return pThreadImpl; + +} + +/*****************************************************************************/ +/* osl_createThread */ +/*****************************************************************************/ +oslThread SAL_CALL osl_createThread(oslWorkerFunction pWorker, + void* pThreadData) +{ + return oslCreateThread(pWorker,pThreadData,sal_False); +} + +/*****************************************************************************/ +/* osl_createSuspendedThread */ +/*****************************************************************************/ +oslThread SAL_CALL osl_createSuspendedThread(oslWorkerFunction pWorker, + void* pThreadData) +{ + return oslCreateThread(pWorker,pThreadData,sal_True); +} + +/*****************************************************************************/ +/* osl_getThreadIdentifier */ +/*****************************************************************************/ +oslThreadIdentifier SAL_CALL osl_getThreadIdentifier(oslThread Thread) +{ + osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread; + + if (pThreadImpl != NULL) + return ((oslThreadIdentifier)pThreadImpl->m_ThreadId); + else + { + PTIB pptib = NULL; + PPIB pppib = NULL; + + DosGetInfoBlocks( &pptib, &pppib ); + return ((oslThreadIdentifier) pptib->tib_ptib2->tib2_ultid ); + } +} + +/*****************************************************************************/ +/* osl_destroyThread */ +/*****************************************************************************/ +void SAL_CALL osl_destroyThread(oslThread Thread) +{ + osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread; + + if(Thread == 0) /* valid ptr? */ + { + /* thread already destroyed or not created */ + return; + } + + if(pThreadImpl->m_ThreadId != -1) /* valid handle ? */ + { + /* cancel thread */ + DosKillThread( pThreadImpl->m_ThreadId ); + } +} + +/*****************************************************************************/ +/* osl_freeThreadHandle */ +/*****************************************************************************/ +void SAL_CALL osl_freeThreadHandle(oslThread Thread) +{ + osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread; + + if(Thread == 0) /* valid ptr? */ + { + /* thread already destroyed or not created */ + return; + } + + if (pThreadImpl->m_hEvent != 0) + DosCloseEventSem(pThreadImpl->m_hEvent); + + /* free memory */ + free(Thread); +} + +/*****************************************************************************/ +/* osl_resumeThread */ +/*****************************************************************************/ +void SAL_CALL osl_resumeThread(oslThread Thread) +{ + osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread; + + OSL_ASSERT(pThreadImpl); /* valid ptr? */ + + DosResumeThread( pThreadImpl->m_ThreadId ); +} + +/*****************************************************************************/ +/* osl_suspendThread */ +/*****************************************************************************/ +void SAL_CALL osl_suspendThread(oslThread Thread) +{ + osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread; + + OSL_ASSERT(pThreadImpl); /* valid ptr? */ + + DosSuspendThread( pThreadImpl->m_ThreadId ); +} + +/*****************************************************************************/ +/* osl_setThreadPriority */ +/*****************************************************************************/ +void SAL_CALL osl_setThreadPriority(oslThread Thread, + oslThreadPriority Priority) +{ + ULONG nOs2PriorityClass; + ULONG nOs2PriorityDelta; + osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread; + + OSL_ASSERT(pThreadImpl); /* valid ptr? */ + + switch(Priority) { + + case osl_Thread_PriorityHighest: + + nOs2PriorityClass = PRTYC_REGULAR; + nOs2PriorityDelta = PRTYD_MAXIMUM; + break; + + case osl_Thread_PriorityAboveNormal: + + nOs2PriorityClass = PRTYC_REGULAR; + nOs2PriorityDelta = 16; + break; + + case osl_Thread_PriorityNormal: + + nOs2PriorityClass = PRTYC_REGULAR; + nOs2PriorityDelta = 0; + break; + + case osl_Thread_PriorityBelowNormal: + + nOs2PriorityClass = PRTYC_REGULAR; + nOs2PriorityDelta = -16; + break; + + case osl_Thread_PriorityLowest: + + nOs2PriorityClass = PRTYC_REGULAR; + nOs2PriorityDelta = PRTYD_MINIMUM; + break; + + case osl_Thread_PriorityUnknown: + OSL_ASSERT(FALSE); /* only fools try this...*/ + + /* let release-version behave friendly */ + return; + + default: + OSL_ASSERT(FALSE); /* enum expanded, but forgotten here...*/ + + /* let release-version behave friendly */ + return; + } + + DosSetPriority( PRTYS_THREAD, + nOs2PriorityClass, nOs2PriorityDelta, + pThreadImpl->m_ThreadId ); + +} + +/*****************************************************************************/ +/* osl_getThreadPriority */ +/*****************************************************************************/ + +#define BYTE1FROMULONG(ul) ((UCHAR) (ul)) +#define BYTE2FROMULONG(ul) ((UCHAR) ((ULONG) ul >> 8)) + +oslThreadPriority SAL_CALL osl_getThreadPriority(const oslThread Thread) +{ + ULONG nOs2PriorityClass; + ULONG nOs2PriorityDelta; + + oslThreadPriority Priority; + + osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread; + + /* invalid arguments ?*/ + if(pThreadImpl==0 || pThreadImpl->m_ThreadId==-1) + { + return osl_Thread_PriorityUnknown; + } + + /* get current priorities */ + { + PTIB pptib = NULL; + PPIB pppib = NULL; + + DosGetInfoBlocks( &pptib, &pppib ); + nOs2PriorityClass = BYTE1FROMULONG( pptib->tib_ptib2->tib2_ulpri ); + nOs2PriorityDelta = BYTE2FROMULONG( pptib->tib_ptib2->tib2_ulpri ); + } + + /* map OS2 priority to enum */ + switch(nOs2PriorityClass) + { + case PRTYC_TIMECRITICAL: + Priority= osl_Thread_PriorityHighest; + break; + + case PRTYC_REGULAR: + + if( nOs2PriorityDelta == 0 ) + { + Priority= osl_Thread_PriorityNormal; + break; + } + + if( nOs2PriorityDelta < -16 ) + { + Priority= osl_Thread_PriorityLowest; + break; + } + + if( nOs2PriorityDelta < 0 ) + { + Priority= osl_Thread_PriorityBelowNormal; + break; + } + + if( nOs2PriorityDelta > 0 ) + { + Priority= osl_Thread_PriorityAboveNormal; + break; + } + + Priority= osl_Thread_PriorityHighest; + break; + + case PRTYC_IDLETIME: + Priority= osl_Thread_PriorityLowest; + break; + + default: + OSL_ASSERT(FALSE); /* OS/2 API changed, incorporate new prio-level! */ + + /* release-version behaves friendly */ + Priority= osl_Thread_PriorityUnknown; + } + + return Priority; +} + +/*****************************************************************************/ +/* osl_isThreadRunning */ +/*****************************************************************************/ +sal_Bool SAL_CALL osl_isThreadRunning(const oslThread Thread) +{ + osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread; + APIRET rc; + + /* invalid arguments ?*/ + if(pThreadImpl==0 || pThreadImpl->m_ThreadId==-1) + { + return sal_False; + } + + if( osl_getThreadIdentifier( 0 ) == osl_getThreadIdentifier( Thread ) ) + return sal_True; + + rc = DosWaitThread( &pThreadImpl->m_ThreadId, DCWW_NOWAIT ); + + return( rc != ERROR_INVALID_THREADID ); +} + +/*****************************************************************************/ +/* osl_joinWithThread */ +/*****************************************************************************/ +void SAL_CALL osl_joinWithThread(oslThread Thread) +{ + osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread; + + /* invalid arguments?*/ + if(pThreadImpl==0 || pThreadImpl->m_ThreadId==-1) + { + /* assume thread is not running */ + return; + } + + DosWaitThread( &pThreadImpl->m_ThreadId, DCWW_WAIT ); +} + +/*****************************************************************************/ +/* osl_sleepThread */ +/*****************************************************************************/ +#if 0 // YD +oslThreadSleep SAL_CALL osl_sleepThread(oslThread Thread, const TimeValue* pDelay) +{ + TID tidCurrentThread; + APIRET rc; + ULONG ulPostCount; + int millisecs; + + osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread; + + OSL_ASSERT(pDelay); + + /* invalid arguments?*/ + if(pThreadImpl==0 || pThreadImpl->m_ThreadId==-1) + return osl_Thread_SleepError; + + if (pThreadImpl->m_Flags & THREADIMPL_FLAGS_SLEEP) + return osl_Thread_SleepActive; + + DosEnterCritSec(); + + if (pThreadImpl->m_hEvent == 0) + rc = DosCreateEventSem( NULL, /* unnamed semaphore */ + &pThreadImpl->m_hEvent, /* pointer to variable */ + /* for the sem-handle */ + DC_SEM_SHARED, /* shared semaphore */ + FALSE ); /* initial state is posted */ + else + DosResetEventSem(pThreadImpl->m_hEvent, &ulPostCount); + + /* get thread ID */ + { + PTIB pptib = NULL; + PPIB pppib = NULL; + + DosGetInfoBlocks( &pptib, &pppib ); + tidCurrentThread = pptib->tib_ptib2->tib2_ultid; + } + + millisecs = pDelay->Seconds * 1000 + pDelay->Nanosec / 1000000; + + if (pThreadImpl->m_ThreadId == tidCurrentThread) + { + pThreadImpl->m_Timeout = 0; + pThreadImpl->m_Flags |= THREADIMPL_FLAGS_SLEEP; + + DosExitCritSec(); + + rc = DosWaitEventSem(pThreadImpl->m_hEvent, millisecs); + + DosEnterCritSec(); + + pThreadImpl->m_Flags &= ~THREADIMPL_FLAGS_SLEEP; + + DosExitCritSec(); + + return (rc == ERROR_TIMEOUT) ? osl_Thread_SleepNormal : + osl_Thread_SleepCancel; + } + else + { + pThreadImpl->m_Timeout = millisecs; + pThreadImpl->m_Flags |= THREADIMPL_FLAGS_SLEEP; + + DosExitCritSec(); + + return osl_Thread_SleepPending; + } +} + +/*****************************************************************************/ +/* osl_awakeThread */ +/*****************************************************************************/ +sal_Bool SAL_CALL osl_awakeThread(oslThread Thread) +{ + osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread; + + /* invalid arguments?*/ + if (pThreadImpl==0 || pThreadImpl->m_ThreadId==-1) + { + /* assume thread is not running */ + return sal_False; + } + + DosEnterCritSec(); + + if (pThreadImpl->m_Flags & THREADIMPL_FLAGS_SLEEP) + { + DosPostEventSem(pThreadImpl->m_hEvent); + + DosExitCritSec(); + return sal_True; + } + else + { + DosExitCritSec(); + return sal_True; + } +} +#endif // 0 YD + +/*****************************************************************************/ +/* osl_waitThread */ +/*****************************************************************************/ +void SAL_CALL osl_waitThread(const TimeValue* pDelay) +{ + int millisecs; + + OSL_ASSERT(pDelay); + + millisecs = pDelay->Seconds * 1000 + pDelay->Nanosec / 1000000; + + DosSleep(millisecs); +} + +/*****************************************************************************/ +/* osl_terminateThread */ +/*****************************************************************************/ +void SAL_CALL osl_terminateThread(oslThread Thread) +{ + osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread; + + /* invalid arguments?*/ + if (pThreadImpl==0 || pThreadImpl->m_ThreadId==-1) + { + /* assume thread is not running */ + return; + } + + DosEnterCritSec(); + pThreadImpl->m_Flags |= THREADIMPL_FLAGS_TERMINATE; + DosExitCritSec(); +} + + +/*****************************************************************************/ +/* osl_scheduleThread */ +/*****************************************************************************/ +sal_Bool SAL_CALL osl_scheduleThread(oslThread Thread) +{ + osl_TThreadImpl* pThreadImpl= (osl_TThreadImpl*)Thread; + + osl_yieldThread(); + + /* invalid arguments?*/ + if (pThreadImpl==0 || pThreadImpl->m_ThreadId==-1) + { + /* assume thread is not running */ + return sal_False; + } + + if (pThreadImpl->m_Flags & THREADIMPL_FLAGS_SLEEP) + { + OSL_ASSERT (pThreadImpl->m_hEvent != 0); + + DosWaitEventSem(pThreadImpl->m_hEvent, pThreadImpl->m_Timeout); + + DosEnterCritSec(); + + pThreadImpl->m_Timeout = 0; + + pThreadImpl->m_Flags &= ~THREADIMPL_FLAGS_SLEEP; + + DosExitCritSec(); + } + + return ((pThreadImpl->m_Flags & THREADIMPL_FLAGS_TERMINATE) == 0); +} + +/*****************************************************************************/ +/* osl_yieldThread */ +/*****************************************************************************/ +void SAL_CALL osl_yieldThread() +{ + DosSleep(0); +} + +typedef struct _TLS +{ + //ULONG dwIndex; + PULONG pulPtr; + oslThreadKeyCallbackFunction pfnCallback; + struct _TLS *pNext, *pPrev; +} TLS, *PTLS; + +static PTLS g_pThreadKeyList = NULL; + +static void AddKeyToList( PTLS pTls ) +{ + if ( pTls ) + { + DosEnterCritSec(); + + pTls->pNext = g_pThreadKeyList; + pTls->pPrev = 0; + + if ( g_pThreadKeyList ) + g_pThreadKeyList->pPrev = pTls; + + g_pThreadKeyList = pTls; + + DosExitCritSec(); + } +} + +static void RemoveKeyFromList( PTLS pTls ) +{ + if ( pTls ) + { + DosEnterCritSec(); + if ( pTls->pPrev ) + pTls->pPrev->pNext = pTls->pNext; + else + { + OSL_ASSERT( pTls == g_pThreadKeyList ); + g_pThreadKeyList = pTls->pNext; + } + + if ( pTls->pNext ) + pTls->pNext->pPrev = pTls->pPrev; + DosExitCritSec(); + } +} + +void SAL_CALL _osl_callThreadKeyCallbackOnThreadDetach(void) +{ + PTLS pTls; + + DosEnterCritSec(); + pTls = g_pThreadKeyList; + while ( pTls ) + { + if ( pTls->pfnCallback ) + { + void *pValue = (void*)*pTls->pulPtr; + + if ( pValue ) + pTls->pfnCallback( pValue ); + } + + pTls = pTls->pNext; + } + DosExitCritSec(); +} + +/*****************************************************************************/ +/* osl_createThreadKey */ +/*****************************************************************************/ +oslThreadKey SAL_CALL osl_createThreadKey(oslThreadKeyCallbackFunction pCallback) +{ + PTLS pTls = (PTLS)rtl_allocateMemory( sizeof(TLS) ); + + if ( pTls ) + { + pTls->pfnCallback = pCallback; + if (DosAllocThreadLocalMemory(1, &pTls->pulPtr) != NO_ERROR) + { + rtl_freeMemory( pTls ); + pTls = 0; + } + else + { + *pTls->pulPtr = 0; + AddKeyToList( pTls ); + } + } + + return ((oslThreadKey)pTls); +} + +/*****************************************************************************/ +/* osl_destroyThreadKey */ +/*****************************************************************************/ +void SAL_CALL osl_destroyThreadKey(oslThreadKey Key) +{ + if (Key != 0) + { + PTLS pTls = (PTLS)Key; + + RemoveKeyFromList( pTls ); + DosFreeThreadLocalMemory(pTls->pulPtr); + rtl_freeMemory( pTls ); + } +} + +/*****************************************************************************/ +/* osl_getThreadKeyData */ +/*****************************************************************************/ +void * SAL_CALL osl_getThreadKeyData(oslThreadKey Key) +{ + if (Key != 0) + { + PTLS pTls = (PTLS)Key; + + return ((void *) *pTls->pulPtr); + } + + return (NULL); +} + +/*****************************************************************************/ +/* osl_setThreadKeyData */ +/*****************************************************************************/ +sal_Bool SAL_CALL osl_setThreadKeyData(oslThreadKey Key, void *pData) +{ + if (Key != 0) + { + PTLS pTls = (PTLS)Key; + void* pOldData = NULL; + BOOL fSuccess = TRUE; //YD cannot fail + + if ( pTls->pfnCallback ) + pOldData = (void*)*pTls->pulPtr; + + *pTls->pulPtr = (ULONG)pData; + + if ( fSuccess && pTls->pfnCallback && pOldData ) + pTls->pfnCallback( pOldData ); + + return (sal_Bool)(fSuccess != FALSE); + } + + return (sal_False); +} + + + +/*****************************************************************************/ +/* osl_getThreadTextEncoding */ +/*****************************************************************************/ + +ULONG g_dwTLSTextEncodingIndex = (ULONG)-1; + +sal_uInt32 SAL_CALL _GetACP( void) +{ + APIRET rc; + ULONG aulCpList[8] = {0}; + ULONG ulListSize; + + rc = DosQueryCp( sizeof( aulCpList), aulCpList, &ulListSize); + if (rc) + return 437; // in case of error, return codepage EN_US + // current codepage is first of list, others are the prepared codepages. + return aulCpList[0]; +} + +rtl_TextEncoding SAL_CALL osl_getThreadTextEncoding(void) +{ + rtl_TextEncoding _encoding; + + if ( (ULONG)-1 == g_dwTLSTextEncodingIndex ) { + rtl_TextEncoding defaultEncoding; + const char * pszEncoding; + + /* create thread specific data key */ + g_dwTLSTextEncodingIndex = osl_createThreadKey( NULL); + + /* determine default text encoding */ + pszEncoding = getenv ("SOLAR_USER_RTL_TEXTENCODING"); + if (pszEncoding) + defaultEncoding = atoi(pszEncoding); + else + defaultEncoding = rtl_getTextEncodingFromWindowsCodePage( _GetACP()); + + //OSL_ASSERT(defaultEncoding != RTL_TEXTENCODING_DONTKNOW); + //g_thread.m_textencoding.m_default = defaultEncoding; + osl_setThreadKeyData( g_dwTLSTextEncodingIndex, (void*)defaultEncoding); + } + + _encoding = (rtl_TextEncoding)osl_getThreadKeyData( g_dwTLSTextEncodingIndex ); + if (0 == _encoding) { + const char * pszEncoding; + /* determine default text encoding */ + pszEncoding = getenv ("SOLAR_USER_RTL_TEXTENCODING"); + if (pszEncoding) + _encoding = atoi(pszEncoding); + else + _encoding = rtl_getTextEncodingFromWindowsCodePage( _GetACP()); + /* save for future reference */ + osl_setThreadKeyData( g_dwTLSTextEncodingIndex, (void*)_encoding); + } + + return _encoding; +} + +/*****************************************************************************/ +/* osl_getThreadTextEncoding */ +/*****************************************************************************/ +rtl_TextEncoding SAL_CALL osl_setThreadTextEncoding( rtl_TextEncoding Encoding ) +{ + rtl_TextEncoding oldEncoding = osl_getThreadTextEncoding(); + + osl_setThreadKeyData( g_dwTLSTextEncodingIndex, (void*)Encoding); + + return oldEncoding; +} + + + |