summaryrefslogtreecommitdiff
path: root/Source/Core/Common
diff options
context:
space:
mode:
authorArmada <jules.blok@gmail.com>2013-06-15 13:21:57 +0200
committerArmada <jules.blok@gmail.com>2013-06-16 12:33:13 +0200
commitfc7099a9057ee962ea4fd43bf049396d86065cf0 (patch)
treeccdaf5bdbce24c9366fae3bbd1a988b4e1886d3b /Source/Core/Common
parent825c5ca09a999aa492bd1137babef5540ff5956e (diff)
Set the locale per-thread instead of globally when generating shaders. Add cross-compatible versions of newlocale, uselocale and freelocale.
This commit fixes a rare race condition when generating shaders because setlocale is global.
Diffstat (limited to 'Source/Core/Common')
-rw-r--r--Source/Core/Common/Src/CommonFuncs.h39
1 files changed, 39 insertions, 0 deletions
diff --git a/Source/Core/Common/Src/CommonFuncs.h b/Source/Core/Common/Src/CommonFuncs.h
index 710c20955e..4321e6dba0 100644
--- a/Source/Core/Common/Src/CommonFuncs.h
+++ b/Source/Core/Common/Src/CommonFuncs.h
@@ -86,6 +86,45 @@ inline u64 _rotr64(u64 x, unsigned int shift){
#define unlink _unlink
#define snprintf _snprintf
#define vscprintf _vscprintf
+
+// Locale Cross-Compatibility
+ #define locale_t _locale_t
+ #define freelocale _free_locale
+ #define newlocale(mask, locale, base) _create_locale(mask, locale)
+
+ #define LC_GLOBAL_LOCALE ((locale_t)-1)
+ #define LC_ALL_MASK LC_ALL
+ #define LC_COLLATE_MASK LC_COLLATE
+ #define LC_CTYPE_MASK LC_CTYPE
+ #define LC_MONETARY_MASK LC_MONETARY
+ #define LC_NUMERIC_MASK LC_NUMERIC
+ #define LC_TIME_MASK LC_TIME
+
+ inline locale_t uselocale(locale_t new_locale)
+ {
+ // Retrieve the current per thread locale setting
+ bool bIsPerThread = (_configthreadlocale(0) == _ENABLE_PER_THREAD_LOCALE);
+
+ // Retrieve the current thread-specific locale
+ locale_t old_locale = bIsPerThread ? _get_current_locale() : LC_GLOBAL_LOCALE;
+
+ if(new_locale == LC_GLOBAL_LOCALE)
+ {
+ // Restore the global locale
+ _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
+ }
+ else if(new_locale != NULL)
+ {
+ // Configure the thread to set the locale only for this thread
+ _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
+
+ // Set all locale categories
+ for(int i = LC_MIN; i <= LC_MAX; i++)
+ setlocale(i, new_locale->locinfo->lc_category[i].locale);
+ }
+
+ return old_locale;
+ }
// 64 bit offsets for windows
#define fseeko _fseeki64