ReactOS 0.4.16-dev-822-gbcedb53
per_thread_data.cpp File Reference
#include <corecrt_internal.h>
#include <corecrt_internal_ptd_propagation.h>
#include <stddef.h>
Include dependency graph for per_thread_data.cpp:

Go to the source code of this file.

Functions

static void WINAPI destroy_fls (void *) throw ()
 
bool __cdecl __acrt_initialize_ptd ()
 
bool __cdecl __acrt_uninitialize_ptd (bool)
 
static void __cdecl replace_current_thread_locale_nolock (__acrt_ptd *const ptd, __crt_locale_data *const new_locale_info) throw ()
 
static void __cdecl construct_ptd (__acrt_ptd *const ptd, __crt_locale_data **const locale_data) throw ()
 
static void __cdecl construct_ptd_array (__acrt_ptd *const ptd) throw ()
 
static void __cdecl destroy_ptd (__acrt_ptd *const ptd) throw ()
 
static void __cdecl destroy_ptd_array (__acrt_ptd *const ptd) throw ()
 
static __forceinline __acrt_ptdtry_get_ptd_head () throw ()
 
 _Success_ (return !=nullptr) static __forceinline __acrt_ptd *internal_get_ptd_head() throw ()
 
static __forceinline __acrt_ptd *__cdecl internal_getptd_noexit (__crt_scoped_get_last_error_reset const &last_error_reset, size_t const global_state_index) throw ()
 
static __forceinline __acrt_ptd *__cdecl internal_getptd_noexit () throw ()
 
__acrt_ptd *__cdecl __acrt_getptd_noexit_explicit (__crt_scoped_get_last_error_reset const &last_error_reset, size_t const global_state_index)
 
__acrt_ptd *__cdecl __acrt_getptd_noexit ()
 
__acrt_ptd *__cdecl __acrt_getptd ()
 
__acrt_ptd *__cdecl __acrt_getptd_head ()
 
void __cdecl __acrt_freeptd ()
 
unsigned long __cdecl __threadid ()
 
uintptr_t __cdecl __threadhandle ()
 

Variables

static unsigned long __acrt_flsindex = FLS_OUT_OF_INDEXES
 

Function Documentation

◆ __acrt_freeptd()

void __cdecl __acrt_freeptd ( void  )

Definition at line 322 of file per_thread_data.cpp.

323{
324 __acrt_ptd* const ptd_head = try_get_ptd_head();
325 if (!ptd_head)
326 {
327 return;
328 }
329
331 destroy_fls(ptd_head);
332}
BOOL WINAPI __acrt_FlsSetValue(_In_ DWORD dwFlsIndex, _In_opt_ PVOID lpFlsData)
static void WINAPI destroy_fls(void *)
static unsigned long __acrt_flsindex
static __forceinline __acrt_ptd * try_get_ptd_head()

Referenced by __acrt_thread_detach().

◆ __acrt_getptd()

◆ __acrt_getptd_head()

__acrt_ptd *__cdecl __acrt_getptd_head ( void  )

Definition at line 309 of file per_thread_data.cpp.

310{
311 __acrt_ptd* const ptd_head = internal_get_ptd_head();
312 if (!ptd_head)
313 {
314 abort();
315 }
316
317 return ptd_head;
318}

Referenced by __acrt_initialize_multibyte().

◆ __acrt_getptd_noexit()

◆ __acrt_getptd_noexit_explicit()

__acrt_ptd *__cdecl __acrt_getptd_noexit_explicit ( __crt_scoped_get_last_error_reset const last_error_reset,
size_t const  global_state_index 
)

Definition at line 286 of file per_thread_data.cpp.

287{ // An extra function to grab the PTD while a GetLastError() reset guard is already in place
288 // and the global state index is already known.
289
290 return internal_getptd_noexit(last_error_reset, global_state_index);
291}

◆ __acrt_initialize_ptd()

bool __cdecl __acrt_initialize_ptd ( void  )

Definition at line 28 of file per_thread_data.cpp.

29{
32 {
33 return false;
34 }
35
36 if (__acrt_getptd_noexit() == nullptr)
37 {
39 return false;
40 }
41
42 return true;
43}
DWORD WINAPI __acrt_FlsAlloc(_In_opt_ PFLS_CALLBACK_FUNCTION lpCallback)
__acrt_ptd *__cdecl __acrt_getptd_noexit()
bool __cdecl __acrt_uninitialize_ptd(bool)
#define FLS_OUT_OF_INDEXES
Definition: winbase.h:602

◆ __acrt_uninitialize_ptd()

bool __cdecl __acrt_uninitialize_ptd ( bool  )

Definition at line 45 of file per_thread_data.cpp.

46{
48 {
51 }
52
53 return true;
54}
BOOL WINAPI __acrt_FlsFree(_In_ DWORD dwFlsIndex)

Referenced by __acrt_initialize_ptd().

◆ __threadhandle()

uintptr_t __cdecl __threadhandle ( void  )

Definition at line 342 of file per_thread_data.cpp.

343{
344 return reinterpret_cast<uintptr_t>(GetCurrentThread());
345}
unsigned int uintptr_t
Definition: intrin.h:47
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1148

◆ __threadid()

unsigned long __cdecl __threadid ( void  )

This file has no copyright assigned and is placed in the Public Domain. This file is part of the w64 mingw-runtime package. No warranty is given; refer to the file DISCLAIMER within this package.

Definition at line 337 of file per_thread_data.cpp.

338{
339 return GetCurrentThreadId();
340}
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459

◆ _Success_()

_Success_ ( return = nullptr)
throw (
)

Definition at line 217 of file per_thread_data.cpp.

219{
220 // We use the CRT heap to allocate the PTD. If the CRT heap fails to
221 // allocate the requested memory, it will attempt to set errno to ENOMEM,
222 // which will in turn attempt to acquire the PTD, resulting in infinite
223 // recursion that causes a stack overflow.
224 //
225 // We set the PTD to this sentinel value for the duration of the allocation
226 // in order to detect this case.
227 static void* const reentrancy_sentinel = reinterpret_cast<void*>(SIZE_MAX);
228
229 __acrt_ptd* const existing_ptd_head = try_get_ptd_head();
230 if (existing_ptd_head == reentrancy_sentinel)
231 {
232 return nullptr;
233 }
234 else if (existing_ptd_head != nullptr)
235 {
236 return existing_ptd_head;
237 }
238
239 if (!__acrt_FlsSetValue(__acrt_flsindex, reentrancy_sentinel))
240 {
241 return nullptr;
242 }
243
244 __crt_unique_heap_ptr<__acrt_ptd> new_ptd_head(_calloc_crt_t(__acrt_ptd, __crt_state_management::state_index_count));
245 if (!new_ptd_head)
246 {
248 return nullptr;
249 }
250
251 if (!__acrt_FlsSetValue(__acrt_flsindex, new_ptd_head.get()))
252 {
254 return nullptr;
255 }
256
257 construct_ptd_array(new_ptd_head.get());
258 return new_ptd_head.detach();
259}
static void __cdecl construct_ptd_array(__acrt_ptd *const ptd)
#define SIZE_MAX
Definition: compat.h:66

◆ construct_ptd()

static void __cdecl construct_ptd ( __acrt_ptd *const  ptd,
__crt_locale_data **const  locale_data 
)
throw (
)
static

Definition at line 84 of file per_thread_data.cpp.

88{
89 ptd->_rand_state = 1;
90 ptd->_pxcptacttab = const_cast<__crt_signal_action_t*>(__acrt_exception_action_table);
91
92 // It is necessary to always have GLOBAL_LOCALE_BIT set in perthread data
93 // because when doing bitwise or, we won't get __UPDATE_LOCALE to work when
94 // global per thread locale is set.
95 // See _configthreadlocale() and __acrt_should_sync_with_global_locale().
96 ptd->_own_locale = _GLOBAL_LOCALE_BIT;
97
98 ptd->_multibyte_info = &__acrt_initial_multibyte_data;
99
100 // Initialize _setloc_data. These are the only valuse that need to be
101 // initialized.
102 ptd->_setloc_data._cachein[0] = L'C';
103 ptd->_setloc_data._cacheout[0] = L'C';
104
105 // Downlevel data is not initially used
106 ptd->_setloc_downlevel_data = nullptr;
107
108 __acrt_lock_and_call(__acrt_multibyte_cp_lock, [&]
109 {
110 _InterlockedIncrement(&ptd->_multibyte_info->refcount);
111 });
112
113 // We need to make sure that ptd->ptlocinfo in never nullptr, this saves us
114 // perf counts when UPDATING locale.
115 __acrt_lock_and_call(__acrt_locale_lock, [&]
116 {
118 });
119}
@ __acrt_locale_lock
@ __acrt_multibyte_cp_lock
struct __crt_signal_action_t const __acrt_exception_action_table[]
__crt_multibyte_data __acrt_initial_multibyte_data
Definition: mbctype.cpp:42
#define _GLOBAL_LOCALE_BIT
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
#define L(x)
Definition: ntvdm.h:50
static void __cdecl replace_current_thread_locale_nolock(__acrt_ptd *const ptd, __crt_locale_data *const new_locale_info)

Referenced by construct_ptd_array().

◆ construct_ptd_array()

static void __cdecl construct_ptd_array ( __acrt_ptd *const  ptd)
throw (
)
static

Definition at line 123 of file per_thread_data.cpp.

124{
125 for (size_t i = 0; i != __crt_state_management::state_index_count; ++i)
126 {
127 construct_ptd(&ptd[i], &__acrt_current_locale_data.dangerous_get_state_array()[i]);
128 }
129}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
__crt_state_management::dual_state_global< __crt_locale_data * > __acrt_current_locale_data
Definition: nlsdata.cpp:132
static void __cdecl construct_ptd(__acrt_ptd *const ptd, __crt_locale_data **const locale_data)

Referenced by _Success_().

◆ destroy_fls()

static void WINAPI destroy_fls ( void pfd)
throw (
)
static

Definition at line 189 of file per_thread_data.cpp.

190{
191 if (!pfd)
192 {
193 return;
194 }
195
196 destroy_ptd_array(static_cast<__acrt_ptd*>(pfd));
197 _free_crt(pfd);
198}
#define _free_crt
static void __cdecl destroy_ptd_array(__acrt_ptd *const ptd)
static PIXELFORMATDESCRIPTOR pfd
Definition: ssstars.c:67

Referenced by __acrt_freeptd(), and __acrt_initialize_ptd().

◆ destroy_ptd()

static void __cdecl destroy_ptd ( __acrt_ptd *const  ptd)
throw (
)
static

Definition at line 133 of file per_thread_data.cpp.

134{
135 if (ptd->_pxcptacttab != __acrt_exception_action_table)
136 {
137 _free_crt(ptd->_pxcptacttab);
138 }
139
140 _free_crt(ptd->_cvtbuf);
141 _free_crt(ptd->_asctime_buffer);
142 _free_crt(ptd->_wasctime_buffer);
143 _free_crt(ptd->_gmtime_buffer);
144 _free_crt(ptd->_tmpnam_narrow_buffer);
145 _free_crt(ptd->_tmpnam_wide_buffer);
146 _free_crt(ptd->_strerror_buffer);
147 _free_crt(ptd->_wcserror_buffer);
148 _free_crt(ptd->_beginthread_context);
149
150 __acrt_lock_and_call(__acrt_multibyte_cp_lock, [&]
151 {
152 __crt_multibyte_data* const multibyte_data = ptd->_multibyte_info;
153 if (!multibyte_data)
154 {
155 return;
156 }
157
158 if (_InterlockedDecrement(&multibyte_data->refcount) != 0)
159 {
160 return;
161 }
162
163 if (multibyte_data == &__acrt_initial_multibyte_data)
164 {
165 return;
166 }
167
168 _free_crt(multibyte_data);
169 });
170
171 __acrt_lock_and_call(__acrt_locale_lock, [&]
172 {
174 });
175}
long __cdecl _InterlockedDecrement(_Interlocked_operand_ long volatile *_Addend)
if(dx< 0)
Definition: linetemp.h:194

Referenced by destroy_ptd_array().

◆ destroy_ptd_array()

static void __cdecl destroy_ptd_array ( __acrt_ptd *const  ptd)
throw (
)
static

Definition at line 179 of file per_thread_data.cpp.

180{
181 for (size_t i = 0; i != __crt_state_management::state_index_count; ++i)
182 {
183 destroy_ptd(&ptd[i]);
184 }
185}
static void __cdecl destroy_ptd(__acrt_ptd *const ptd)

Referenced by destroy_fls().

◆ internal_getptd_noexit() [1/2]

static __forceinline __acrt_ptd *__cdecl internal_getptd_noexit ( )
throw (
)
static

Definition at line 280 of file per_thread_data.cpp.

281{
282 __crt_scoped_get_last_error_reset const last_error_reset;
283 return internal_getptd_noexit(last_error_reset, __crt_state_management::get_current_state_index(last_error_reset));
284}

Referenced by __acrt_getptd(), __acrt_getptd_noexit(), __acrt_getptd_noexit_explicit(), and internal_getptd_noexit().

◆ internal_getptd_noexit() [2/2]

static __forceinline __acrt_ptd *__cdecl internal_getptd_noexit ( __crt_scoped_get_last_error_reset const last_error_reset,
size_t const  global_state_index 
)
throw (
)
static

Definition at line 265 of file per_thread_data.cpp.

269{
270 UNREFERENCED_PARAMETER(last_error_reset);
271 __acrt_ptd* const ptd_head = internal_get_ptd_head();
272 if (!ptd_head)
273 {
274 return nullptr;
275 }
276
277 return ptd_head + global_state_index;
278}
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325

◆ replace_current_thread_locale_nolock()

static void __cdecl replace_current_thread_locale_nolock ( __acrt_ptd *const  ptd,
__crt_locale_data *const  new_locale_info 
)
throw (
)
static

Definition at line 58 of file per_thread_data.cpp.

62{
63 if (ptd->_locale_info)
64 {
65 __acrt_release_locale_ref(ptd->_locale_info);
66 if (ptd->_locale_info != __acrt_current_locale_data.value() &&
67 ptd->_locale_info != &__acrt_initial_locale_data &&
68 ptd->_locale_info->refcount == 0)
69 {
70 __acrt_free_locale(ptd->_locale_info);
71 }
72 }
73
74 ptd->_locale_info = new_locale_info;
75 if (ptd->_locale_info)
76 {
77 __acrt_add_locale_ref(ptd->_locale_info);
78 }
79}
void __cdecl __acrt_release_locale_ref(__crt_locale_data *)
void __cdecl __acrt_free_locale(__crt_locale_data *)
__crt_locale_data __acrt_initial_locale_data
Definition: nlsdata.cpp:92
void __cdecl __acrt_add_locale_ref(__crt_locale_data *)

Referenced by construct_ptd(), and destroy_ptd().

◆ try_get_ptd_head()

static __forceinline __acrt_ptd * try_get_ptd_head ( )
throw (
)
static

Definition at line 200 of file per_thread_data.cpp.

201{
202 // If we haven't allocated per-thread data for this module, return failure:
204 {
205 return nullptr;
206 }
207
208 __acrt_ptd* const ptd_head = static_cast<__acrt_ptd*>(__acrt_FlsGetValue(__acrt_flsindex));
209 if (!ptd_head)
210 {
211 return nullptr;
212 }
213
214 return ptd_head;
215}
PVOID WINAPI __acrt_FlsGetValue(_In_ DWORD dwFlsIndex)

Referenced by __acrt_freeptd(), and _Success_().

Variable Documentation

◆ __acrt_flsindex