← Back to team overview

kicad-developers team mailing list archive

LOCALE_IO thread-local

 

Hi Devs-

We currently have an RAII locale switch (LOCALE_IO) that swaps the global locale to allow floating point handling with decimal points instead of a commas. Because it changes the global locale, we need to be very careful about allowing the user interface to update during the time that it is temporarily set.

The attached patch moves the locale setting into a thread-local setting, allowing us to use standard threading and UI updates.

There are no functionality changes in this patch. This is merely a change in the calling structure that will allow future cleaning of the LOCALE_IO distribution in the code.

I'd greatly appreciate any windows testing.

Thanks-
Seth
From 8a786debb8c3317e0f44d52b0ec45f89d6286614 Mon Sep 17 00:00:00 2001
From: Seth Hillbrand <hillbrand@xxxxxxxxxxx>
Date: Thu, 20 Jun 2019 20:43:43 -0700
Subject: [PATCH] Move LOCALE_IO to thread-locale storage

Previously, changing the locale required limiting the updates in the
main wx thread.  This sets the locale on a thread-local basis, allowing
the main thread to be unaffected and permitting UI updates during disk
usage.
---
 common/common.cpp | 32 +++++++++++++++++++++++++-------
 include/common.h  |  4 ++++
 2 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/common/common.cpp b/common/common.cpp
index ef4f0c582..8d8aa0830 100644
--- a/common/common.cpp
+++ b/common/common.cpp
@@ -85,14 +85,25 @@ LOCALE_IO::LOCALE_IO()
     // use thread safe, atomic operation
     if( m_c_count++ == 0 )
     {
-        // Store the user locale name, to restore this locale later, in dtor
-        m_user_locale = setlocale( LC_NUMERIC, nullptr );
-#if defined( _WIN32 ) && defined( DEBUG )
+
+        // Switch the locale to C locale, to read/write files with fp numbers
+#ifdef _WIN32
+#ifdef DEBUG
         // Disable wxWidgets alerts
         wxSetAssertHandler( KiAssertFilter );
 #endif
-        // Switch the locale to C locale, to read/write files with fp numbers
+        // Store the user locale name, to restore this locale later, in dtor
+        m_user_locale = setlocale( LC_NUMERIC, nullptr );
+
+        // WINDOW only: Set the locale-per-thread
+        _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
         setlocale( LC_NUMERIC, "C" );
+#else
+
+        // Store the user locale name, to restore this locale later, in dtor
+        m_user_locale = newlocale( LC_NUMERIC_MASK, "C", nullptr );
+        uselocale( m_user_locale );
+#endif
     }
 }
 
@@ -102,12 +113,19 @@ LOCALE_IO::~LOCALE_IO()
     // use thread safe, atomic operation
     if( --m_c_count == 0 )
     {
-        // revert to the user locale
-        setlocale( LC_NUMERIC, m_user_locale.c_str() );
-#if defined( _WIN32 ) && defined( DEBUG )
+#ifdef _WIN32
+#ifdef DEBUG
         // Enable wxWidgets alerts
         wxSetDefaultAssertHandler();
 #endif
+        // revert to the user locale
+        setlocale( LC_NUMERIC, m_user_locale.c_str() );
+#else
+        // revert to the global locale
+        uselocale( LC_GLOBAL_LOCALE );
+        freelocale( m_user_locale );
+#endif
+
     }
 }
 
diff --git a/include/common.h b/include/common.h
index 3d565d955..829817222 100644
--- a/include/common.h
+++ b/include/common.h
@@ -184,9 +184,13 @@ private:
     // allow for nesting of LOCALE_IO instantiations
     static std::atomic<unsigned int> m_c_count;
 
+#ifdef _WIN32
     // The locale in use before switching to the "C" locale
     // (the locale can be set by user, and is not always the system locale)
     std::string m_user_locale;
+#else
+    locale_t m_user_locale;
+#endif
 };
 
 /**
-- 
2.20.1


Follow ups