📄 tidtable.c
字号:
/***
*tidtable.c - Access thread data table
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* This module contains the following routines for multi-thread
* data support:
*
* _mtinit = Initialize the mthread data
* _getptd = get the pointer to the per-thread data structure for
* the current thread
* _freeptd = free up a per-thread data structure and its
* subordinate structures
* __threadid = return thread ID for the current thread
* __threadhandle = return pseudo-handle for the current thread
*
*******************************************************************************/
#include <sect_attribs.h>
#include <cruntime.h>
#include <oscalls.h>
#include <internal.h>
#include <mtdll.h>
#include <memory.h>
#include <msdos.h>
#include <rterr.h>
#include <stdlib.h>
#include <stddef.h>
#include <dbgint.h>
#include <setlocal.h>
#include <mbstring.h>
extern pthreadmbcinfo __ptmbcinfo;
extern threadlocinfo __initiallocinfo;
extern threadmbcinfo __initialmbcinfo;
extern pthreadlocinfo __ptlocinfo;
void * __cdecl __removelocaleref( pthreadlocinfo);
void __cdecl __addlocaleref( pthreadlocinfo);
void __cdecl __freetlocinfo(pthreadlocinfo);
#ifdef _M_IX86
//
// Define Fiber Local Storage function pointers.
//
PFLS_ALLOC_FUNCTION gpFlsAlloc = NULL;
PFLS_GETVALUE_FUNCTION gpFlsGetValue = NULL;
PFLS_SETVALUE_FUNCTION gpFlsSetValue = NULL;
PFLS_FREE_FUNCTION gpFlsFree = NULL;
#endif /* _M_IX86 */
unsigned long __flsindex = FLS_OUT_OF_INDEXES;
#ifdef _M_IX86
unsigned long __getvalueindex = TLS_OUT_OF_INDEXES;
#endif /* _M_IX86 */
/***
*void * _encoded_null() -
*
*Purpose:
* Gets the encoded null pointer for the process
*
*Entry:
* No parameters
*
*Exit:
* The process specific encoding for the null pointer
*
*Exceptions:
*
*******************************************************************************/
_CRTIMP void * __cdecl _encoded_null()
{
return EncodePointer(NULL);
}
#ifdef _M_IX86
/***
* __crtTlsAlloc - crt wrapper around TlsAlloc
*
* Purpose:
* (1) Call to __crtTlsAlloc should look like call to FlsAlloc, this will
* Help in redirecting the call to TlsAlloc and FlsAlloc using same
* redirection variable.
*******************************************************************************/
DWORD WINAPI __crtTlsAlloc( PFLS_CALLBACK_FUNCTION lpCallBack)
{
return TlsAlloc();
}
#endif /* _M_IX86 */
/***
* __fls_getvalue - crt wrapper around FLS_GETVALUE macro
*
* Purpose:
* This function helps msvcmXX.dll beginthread and beginthreadex APIs
* to use FLS_GETVALUE functionsality.
*
*******************************************************************************/
_CRTIMP
PVOID
WINAPI __fls_getvalue (
IN DWORD dwFlsIndex
)
{
return FLS_GETVALUE(dwFlsIndex);
}
/***
* __get_flsindex - crt wrapper around __flsindex
*
* Purpose:
* This function helps msvcmXX.dll beginthread and beginthreadex APIs
* to retrive __flsindex value.
*
*******************************************************************************/
_CRTIMP unsigned long __cdecl __get_flsindex()
{
return __flsindex;
}
/***
* __set_flsgetvalue - crt wrapper for setting up FlsGetValue pointer in TLS
*
* Purpose:
* This function helps msvcmXX.dll threadstart and threadstartex APIs
* to set FlsGetValue pointer before calling __fls_getvalue.
*
*******************************************************************************/
_CRTIMP PFLS_GETVALUE_FUNCTION __cdecl __set_flsgetvalue()
{
#ifdef _M_IX86
PFLS_GETVALUE_FUNCTION flsGetValue = FLS_GETVALUE;
if (!flsGetValue)
{
flsGetValue = DecodePointer(gpFlsGetValue);
TlsSetValue(__getvalueindex, flsGetValue);
}
return flsGetValue;
#else /* _M_IX86 */
return NULL;
#endif /* _M_IX86 */
}
/***
* __fls_setvalue - crt wrapper around FLS_SETVALUE macro
*
* Purpose:
* This function helps msvcmXX.dll beginthread and beginthreadex APIs
* to use FLS_SETVALUE functionsality.
*
*******************************************************************************/
_CRTIMP
BOOL
WINAPI __fls_setvalue (
IN DWORD dwFlsIndex,
IN PVOID lpFlsData
)
{
return FLS_SETVALUE(dwFlsIndex, lpFlsData);
}
/****
*_mtinit() - Init multi-thread data bases
*
*Purpose:
* (1) Call _mtinitlocks to create/open all lock semaphores.
* (2) Allocate a TLS index to hold pointers to per-thread data
* structure.
*
* NOTES:
* (1) Only to be called ONCE at startup
* (2) Must be called BEFORE any mthread requests are made
*
*Entry:
* <NONE>
*Exit:
* returns FALSE on failure
*
*Uses:
* <any registers may be modified at init time>
*
*Exceptions:
*
*******************************************************************************/
int __cdecl _mtinit (
void
)
{
_ptiddata ptd;
#ifdef _M_IX86
/*
* Initialize fiber local storage function pointers.
*/
HINSTANCE hKernel32 = GetModuleHandleW(L"KERNEL32.DLL");
if (hKernel32 == NULL) {
_mtterm();
return FALSE; /* fail to load DLL */
}
gpFlsAlloc = (PFLS_ALLOC_FUNCTION)GetProcAddress(hKernel32,
"FlsAlloc");
gpFlsGetValue = (PFLS_GETVALUE_FUNCTION)GetProcAddress(hKernel32,
"FlsGetValue");
gpFlsSetValue = (PFLS_SETVALUE_FUNCTION)GetProcAddress(hKernel32,
"FlsSetValue");
gpFlsFree = (PFLS_FREE_FUNCTION)GetProcAddress(hKernel32,
"FlsFree");
if (!gpFlsAlloc || !gpFlsGetValue || !gpFlsSetValue || !gpFlsFree) {
gpFlsAlloc = (PFLS_ALLOC_FUNCTION)__crtTlsAlloc;
gpFlsGetValue = (PFLS_GETVALUE_FUNCTION)TlsGetValue;
gpFlsSetValue = (PFLS_SETVALUE_FUNCTION)TlsSetValue;
gpFlsFree = (PFLS_FREE_FUNCTION)TlsFree;
}
/*
* Allocate and initialize a TLS index to store FlsGetValue pointer
* so that the FLS_* macros can work transparently
*/
if ( (__getvalueindex = TlsAlloc()) == TLS_OUT_OF_INDEXES ||
!TlsSetValue(__getvalueindex, (LPVOID)gpFlsGetValue) ) {
return FALSE;
}
#endif /* _M_IX86 */
_init_pointers(); /* initialize global function pointers */
#ifdef _M_IX86
/*
* Encode the fiber local storage function pointers
*/
gpFlsAlloc = (PFLS_ALLOC_FUNCTION) EncodePointer(gpFlsAlloc);
gpFlsGetValue = (PFLS_GETVALUE_FUNCTION) EncodePointer(gpFlsGetValue);
gpFlsSetValue = (PFLS_SETVALUE_FUNCTION) EncodePointer(gpFlsSetValue);
gpFlsFree = (PFLS_FREE_FUNCTION) EncodePointer(gpFlsFree);
#endif /* _M_IX86 */
/*
* Initialize the mthread lock data base
*/
if ( !_mtinitlocks() ) {
_mtterm();
return FALSE; /* fail to load DLL */
}
/*
* Allocate a TLS index to maintain pointers to per-thread data
*/
if ( (__flsindex = FLS_ALLOC(&_freefls)) == FLS_OUT_OF_INDEXES ) {
_mtterm();
return FALSE; /* fail to load DLL */
}
/*
* Create a per-thread data structure for this (i.e., the startup)
* thread.
*/
if ( ((ptd = _calloc_crt(1, sizeof(struct _tiddata))) == NULL) ||
!FLS_SETVALUE(__flsindex, (LPVOID)ptd) )
{
_mtterm();
return FALSE; /* fail to load DLL */
}
/*
* Initialize the per-thread data
*/
_initptd(ptd,NULL);
ptd->_tid = GetCurrentThreadId();
ptd->_thandle = (uintptr_t)(-1);
return TRUE;
}
/****
*_mtterm() - Clean-up multi-thread data bases
*
*Purpose:
* (1) Call _mtdeletelocks to free up all lock semaphores.
* (2) Free up the TLS index used to hold pointers to
* per-thread data structure.
*
* NOTES:
* (1) Only to be called ONCE at termination
* (2) Must be called AFTER all mthread requests are made
*
*Entry:
* <NONE>
*Exit:
* returns
*
*Uses:
*
*Exceptions:
*
*******************************************************************************/
void __cdecl _mtterm (
void
)
{
/*
* Free up the TLS index
*
* (Set the variables __flsindex and __getvalueindex back to initial state (-1L).)
*/
if ( __flsindex != FLS_OUT_OF_INDEXES ) {
FLS_FREE(__flsindex);
__flsindex = FLS_OUT_OF_INDEXES;
}
#ifdef _M_IX86
if ( __getvalueindex != TLS_OUT_OF_INDEXES ) {
TlsFree(__getvalueindex);
__getvalueindex = TLS_OUT_OF_INDEXES;
}
#endif /* _M_IX86 */
/*
* Clean up the mthread lock data base
*/
_mtdeletelocks();
}
/***
*void _initptd(_ptiddata ptd, pthreadlocinfo) - initialize a per-thread data structure
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -