mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 11:53:16 +00:00
[UCRT] Import Microsoft.Windows.SDK.CRTSource version 10.0.22621.3
Imported from https://www.nuget.org/packages/Microsoft.Windows.SDK.CRTSource/10.0.22621.3 License: MIT
This commit is contained in:
parent
f1b60c66f0
commit
04e0dc4a7a
568 changed files with 115483 additions and 0 deletions
353
sdk/lib/ucrt/locale/locale_refcounting.cpp
Normal file
353
sdk/lib/ucrt/locale/locale_refcounting.cpp
Normal file
|
@ -0,0 +1,353 @@
|
|||
/***
|
||||
*localref.c - Contains the __[add|remove]localeref() functions.
|
||||
*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
*
|
||||
*Purpose:
|
||||
* Contains the __[add|remove]localeref() functions.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#include <corecrt_internal.h>
|
||||
#include <locale.h>
|
||||
|
||||
|
||||
|
||||
/***
|
||||
* __acrt_add_locale_ref(__crt_locale_data* ptloci)
|
||||
*
|
||||
* Purpose:
|
||||
* Increment the refrence count for each element in the localeinfo struct.
|
||||
*
|
||||
*******************************************************************************/
|
||||
extern "C" void __cdecl __acrt_add_locale_ref(__crt_locale_data* ptloci)
|
||||
{
|
||||
_InterlockedIncrement(&ptloci->refcount);
|
||||
|
||||
if (ptloci->lconv_intl_refcount != nullptr)
|
||||
{
|
||||
_InterlockedIncrement(ptloci->lconv_intl_refcount);
|
||||
}
|
||||
|
||||
if (ptloci->lconv_mon_refcount != nullptr)
|
||||
{
|
||||
_InterlockedIncrement(ptloci->lconv_mon_refcount);
|
||||
}
|
||||
|
||||
if (ptloci->lconv_num_refcount != nullptr)
|
||||
{
|
||||
_InterlockedIncrement(ptloci->lconv_num_refcount);
|
||||
}
|
||||
|
||||
if (ptloci->ctype1_refcount != nullptr)
|
||||
{
|
||||
_InterlockedIncrement(ptloci->ctype1_refcount);
|
||||
}
|
||||
|
||||
for (int category = LC_MIN; category <= LC_MAX; ++category)
|
||||
{
|
||||
if (ptloci->lc_category[category].wlocale != __acrt_wide_c_locale_string &&
|
||||
ptloci->lc_category[category].wrefcount != nullptr)
|
||||
{
|
||||
_InterlockedIncrement(ptloci->lc_category[category].wrefcount);
|
||||
}
|
||||
|
||||
if (ptloci->lc_category[category].locale != nullptr &&
|
||||
ptloci->lc_category[category].refcount != nullptr)
|
||||
{
|
||||
_InterlockedIncrement(ptloci->lc_category[category].refcount);
|
||||
}
|
||||
}
|
||||
|
||||
__acrt_locale_add_lc_time_reference(ptloci->lc_time_curr);
|
||||
}
|
||||
|
||||
/***
|
||||
* __acrt_release_locale_ref(__crt_locale_data* ptloci)
|
||||
*
|
||||
* Purpose:
|
||||
* Decrement the refrence count for each elemnt in the localeinfo struct.
|
||||
*
|
||||
******************************************************************************/
|
||||
extern "C" void __cdecl __acrt_release_locale_ref(__crt_locale_data* ptloci)
|
||||
{
|
||||
if (ptloci == nullptr)
|
||||
return;
|
||||
|
||||
_InterlockedDecrement(&ptloci->refcount);
|
||||
|
||||
if (ptloci->lconv_intl_refcount != nullptr)
|
||||
_InterlockedDecrement(ptloci->lconv_intl_refcount);
|
||||
|
||||
if (ptloci->lconv_mon_refcount != nullptr)
|
||||
_InterlockedDecrement(ptloci->lconv_mon_refcount);
|
||||
|
||||
if (ptloci->lconv_num_refcount != nullptr)
|
||||
_InterlockedDecrement(ptloci->lconv_num_refcount);
|
||||
|
||||
if (ptloci->ctype1_refcount != nullptr)
|
||||
_InterlockedDecrement(ptloci->ctype1_refcount);
|
||||
|
||||
for (int category = LC_MIN; category <= LC_MAX; ++category)
|
||||
{
|
||||
if (ptloci->lc_category[category].wlocale != __acrt_wide_c_locale_string &&
|
||||
ptloci->lc_category[category].wrefcount != nullptr)
|
||||
{
|
||||
_InterlockedDecrement(ptloci->lc_category[category].wrefcount);
|
||||
}
|
||||
|
||||
if (ptloci->lc_category[category].locale != nullptr &&
|
||||
ptloci->lc_category[category].refcount != nullptr)
|
||||
{
|
||||
_InterlockedDecrement(ptloci->lc_category[category].refcount);
|
||||
}
|
||||
}
|
||||
|
||||
__acrt_locale_release_lc_time_reference(ptloci->lc_time_curr);
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
*__acrt_free_locale() - free __crt_locale_data
|
||||
*
|
||||
*Purpose:
|
||||
* Free up the per-thread locale info structure specified by the passed
|
||||
* pointer.
|
||||
*
|
||||
*Entry:
|
||||
* __crt_locale_data* ptloci
|
||||
*
|
||||
*Exit:
|
||||
*
|
||||
*Exceptions:
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
extern "C" void __cdecl __acrt_free_locale(__crt_locale_data* ptloci)
|
||||
{
|
||||
/*
|
||||
* Free up lconv struct
|
||||
*/
|
||||
if (ptloci->lconv != nullptr &&
|
||||
ptloci->lconv != &__acrt_lconv_c &&
|
||||
ptloci->lconv_intl_refcount != nullptr &&
|
||||
*ptloci->lconv_intl_refcount == 0)
|
||||
{
|
||||
if (ptloci->lconv_mon_refcount != nullptr && *ptloci->lconv_mon_refcount == 0)
|
||||
{
|
||||
_free_crt(ptloci->lconv_mon_refcount);
|
||||
__acrt_locale_free_monetary(ptloci->lconv);
|
||||
}
|
||||
|
||||
if (ptloci->lconv_num_refcount != nullptr && *ptloci->lconv_num_refcount == 0)
|
||||
{
|
||||
_free_crt(ptloci->lconv_num_refcount);
|
||||
__acrt_locale_free_numeric(ptloci->lconv);
|
||||
}
|
||||
|
||||
_free_crt(ptloci->lconv_intl_refcount);
|
||||
_free_crt(ptloci->lconv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free up ctype tables
|
||||
*/
|
||||
if (ptloci->ctype1_refcount != nullptr && *ptloci->ctype1_refcount == 0)
|
||||
{
|
||||
_free_crt(ptloci->ctype1 - _COFFSET);
|
||||
_free_crt(const_cast<unsigned char*>(ptloci->pclmap - _COFFSET - 1));
|
||||
_free_crt(const_cast<unsigned char*>(ptloci->pcumap - _COFFSET - 1));
|
||||
_free_crt(ptloci->ctype1_refcount);
|
||||
}
|
||||
|
||||
__acrt_locale_free_lc_time_if_unreferenced(ptloci->lc_time_curr);
|
||||
|
||||
for (int category = LC_MIN; category <= LC_MAX; ++category)
|
||||
{
|
||||
if (ptloci->lc_category[category].wlocale != __acrt_wide_c_locale_string &&
|
||||
ptloci->lc_category[category].wrefcount != nullptr &&
|
||||
*ptloci->lc_category[category].wrefcount == 0)
|
||||
{
|
||||
_free_crt(ptloci->lc_category[category].wrefcount);
|
||||
_free_crt(ptloci->locale_name[category]);
|
||||
}
|
||||
|
||||
_ASSERTE((ptloci->lc_category[category].locale != nullptr && ptloci->lc_category[category].refcount != nullptr) ||
|
||||
(ptloci->lc_category[category].locale == nullptr && ptloci->lc_category[category].refcount == nullptr));
|
||||
|
||||
if (ptloci->lc_category[category].locale != nullptr &&
|
||||
ptloci->lc_category[category].refcount != nullptr &&
|
||||
*ptloci->lc_category[category].refcount == 0)
|
||||
{
|
||||
_free_crt(ptloci->lc_category[category].refcount);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Free up the __crt_locale_data struct
|
||||
*/
|
||||
_free_crt(ptloci);
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
*
|
||||
* _updatelocinfoEx_nolock(__crt_locale_data* *pptlocid, __crt_locale_data* ptlocis)
|
||||
*
|
||||
* Purpose:
|
||||
* Update *pptlocid to ptlocis. This might include freeing contents of *pptlocid.
|
||||
*
|
||||
******************************************************************************/
|
||||
extern "C" __crt_locale_data* __cdecl _updatetlocinfoEx_nolock(
|
||||
__crt_locale_data** pptlocid,
|
||||
__crt_locale_data* ptlocis
|
||||
)
|
||||
{
|
||||
if (ptlocis == nullptr || pptlocid == nullptr)
|
||||
return nullptr;
|
||||
|
||||
__crt_locale_data* const ptloci = *pptlocid;
|
||||
if (ptloci == ptlocis)
|
||||
return ptlocis;
|
||||
|
||||
/*
|
||||
* Update to the current locale info structure and increment the
|
||||
* reference counts.
|
||||
*/
|
||||
*pptlocid = ptlocis;
|
||||
__acrt_add_locale_ref(ptlocis);
|
||||
|
||||
/*
|
||||
* Decrement the reference counts in the old locale info
|
||||
* structure.
|
||||
*/
|
||||
if (ptloci != nullptr)
|
||||
{
|
||||
__acrt_release_locale_ref(ptloci);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the old locale info structure, if necessary. Must be done
|
||||
* after incrementing reference counts in current locale in case
|
||||
* any refcounts are shared with the old locale.
|
||||
*/
|
||||
if (ptloci != nullptr &&
|
||||
ptloci->refcount == 0 &&
|
||||
ptloci != &__acrt_initial_locale_data)
|
||||
{
|
||||
__acrt_free_locale(ptloci);
|
||||
}
|
||||
|
||||
return ptlocis;
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
*__acrt_update_thread_locale_data() - refresh the thread's locale info
|
||||
*
|
||||
*Purpose:
|
||||
* If this thread does not have it's ownlocale which means that either
|
||||
* ownlocale flag in ptd is not set or ptd->ptloci == nullptr, then Update
|
||||
* the current thread's reference to the locale information to match the
|
||||
* current global locale info. Decrement the reference on the old locale
|
||||
* information struct and if this count is now zero (so that no threads
|
||||
* are using it), free it.
|
||||
*
|
||||
*Entry:
|
||||
*
|
||||
*Exit:
|
||||
*
|
||||
* if (!_getptd()->ownlocale || _getptd()->ptlocinfo == nullptr)
|
||||
* _getptd()->ptlocinfo == __acrt_current_locale_data
|
||||
* else
|
||||
* _getptd()->ptlocinfo
|
||||
*
|
||||
*Exceptions:
|
||||
*
|
||||
*******************************************************************************/
|
||||
extern "C" __crt_locale_data* __cdecl __acrt_update_thread_locale_data()
|
||||
{
|
||||
__crt_locale_data* ptloci = nullptr;
|
||||
__acrt_ptd* const ptd = __acrt_getptd();
|
||||
|
||||
if (__acrt_should_sync_with_global_locale(ptd) || ptd->_locale_info == nullptr)
|
||||
{
|
||||
__acrt_lock(__acrt_locale_lock);
|
||||
__try
|
||||
{
|
||||
ptloci = _updatetlocinfoEx_nolock(&ptd->_locale_info, __acrt_current_locale_data.value());
|
||||
}
|
||||
__finally
|
||||
{
|
||||
__acrt_unlock(__acrt_locale_lock);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ptloci = ptd->_locale_info;
|
||||
}
|
||||
|
||||
if (!ptloci)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
return ptloci;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
//
|
||||
// __crt_lc_time_data reference counting
|
||||
//
|
||||
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// The C locale lc_time data is immutable and persistent. The lc_time data for
|
||||
// any other locale is dynamically allocated (and thus not actually immutable).
|
||||
// The lc_time_curr data member of __crt_locale_data is declared const to help
|
||||
// ensure that code does not accidentally attempt to modify the C locale lc_time
|
||||
// data.
|
||||
//
|
||||
// These functions encapsulate all mutation of the lc_time_curr. They accept a
|
||||
// __crt_lc_time_data const*, handle the C locale as a special case, then cast
|
||||
// away constness to mutate the lc_time data.
|
||||
extern "C" long __cdecl __acrt_locale_add_lc_time_reference(
|
||||
__crt_lc_time_data const* const lc_time
|
||||
)
|
||||
{
|
||||
if (lc_time == nullptr || lc_time == &__lc_time_c)
|
||||
{
|
||||
return LONG_MAX;
|
||||
}
|
||||
|
||||
return _InterlockedIncrement(&const_cast<__crt_lc_time_data*>(lc_time)->refcount);
|
||||
}
|
||||
|
||||
extern "C" long __cdecl __acrt_locale_release_lc_time_reference(
|
||||
__crt_lc_time_data const* const lc_time
|
||||
)
|
||||
{
|
||||
if (lc_time == nullptr || lc_time == &__lc_time_c)
|
||||
{
|
||||
return LONG_MAX;
|
||||
}
|
||||
|
||||
return _InterlockedDecrement(&const_cast<__crt_lc_time_data*>(lc_time)->refcount);
|
||||
}
|
||||
|
||||
extern "C" void __cdecl __acrt_locale_free_lc_time_if_unreferenced(
|
||||
__crt_lc_time_data const* const lc_time
|
||||
)
|
||||
{
|
||||
if (lc_time == nullptr || lc_time == &__lc_time_c)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (__crt_interlocked_read(&lc_time->refcount) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
__acrt_locale_free_time(const_cast<__crt_lc_time_data*>(lc_time));
|
||||
_free_crt(const_cast<__crt_lc_time_data*>(lc_time));
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue