pastebin - collaborative debugging tool
rovema.kpaste.net RSS


RDE: Fix hang in RDS code due to setlocale() abuse in multithreaded application
Posted by Anonymous on Fri 28th Apr 2023 14:55
raw | new post
view followups (newest first): RDE: Fix hang in RDS code due to setlocale() abuse in multithreaded application by Anonymous
modification of post by Anonymous (view diff)

  1. diff --git a/Base/CMakeLists.txt b/Base/CMakeLists.txt
  2. index e5fd783..b3922e1 100644
  3. --- a/Base/CMakeLists.txt
  4. +++ b/Base/CMakeLists.txt
  5. @@ -34,13 +34,15 @@ else(WIN32)
  6.      if(RDE_BUILD)
  7.          set(PROJECT_SOURCE_FILES ${PROJECT_SOURCE_FILES}
  8.              RecursiveSemaphor.cpp
  9. -            PosixSystem.cpp )
  10. +            PosixSystem.cpp
  11. +           RovLocale.cpp )
  12.      else(RDE_BUILD)
  13.    set(PROJECT_SOURCE_FILES ${PROJECT_SOURCE_FILES}
  14.        TraceBack.cpp
  15.        RovFileSystem.cpp
  16.        RecursiveSemaphor.cpp
  17. -      PosixSystem.cpp )
  18. +      PosixSystem.cpp
  19. +      RovLocale.cpp )
  20.    endif(RDE_BUILD)
  21.  endif(WIN32)
  22.  
  23. diff --git a/Base/PosixSystem.hpp b/Base/PosixSystem.hpp
  24. index 9ec356a..cf7e2c7 100755
  25. --- a/Base/PosixSystem.hpp
  26. +++ b/Base/PosixSystem.hpp
  27. @@ -17,6 +17,7 @@
  28.  #endif
  29.  #include <time.h>
  30.  #include <pthread.h>
  31. +#include <locale.h>
  32.  #include <sys/socket.h>
  33.  #include <sys/types.h>
  34.  #include <sys/ipc.h>
  35. @@ -40,6 +41,8 @@
  36.  
  37.  #undef TEST_REALTIME
  38.  
  39. +extern locale_t rov_get_posix_localeobj(void);
  40. +
  41.  extern void dumpBackTrace( ostream & _outStr );
  42.  
  43.  //-DEFINES/MACROS--------------------------------------------------------------
  44. diff --git a/Base/RovLocale.cpp b/Base/RovLocale.cpp
  45. new file mode 100644
  46. index 0000000..90e735b
  47. --- /dev/null
  48. +++ b/Base/RovLocale.cpp
  49. @@ -0,0 +1,18 @@
  50. +
  51. +#include "PosixSystem.hpp"
  52. +
  53. +pthread_once_t posix_localeobj_init = PTHREAD_ONCE_INIT;
  54. +
  55. +static locale_t posix_localeobj = 0;
  56. +
  57. +static void init_posix_localeobj(void)
  58. +{
  59. +       posix_localeobj = newlocale(LC_ALL_MASK, "POSIX", (locale_t)0);
  60. +}
  61. +
  62. +locale_t rov_get_posix_localeobj(void)
  63. +{
  64. +       (void)pthread_once(&posix_localeobj_init, init_posix_localeobj);
  65. +      
  66. +       return posix_localeobj;
  67. +}
  68. diff --git a/Rdc/RdsTypes.cpp b/Rdc/RdsTypes.cpp
  69. index 213cabd..6b6861c 100755
  70. --- a/Rdc/RdsTypes.cpp
  71. +++ b/Rdc/RdsTypes.cpp
  72. @@ -619,8 +619,15 @@ RINLINE T_Bool g_ReadNumericalValueFromString (
  73.                                                )
  74.  {
  75.  #ifdef JNA
  76. -  std::locale actualLocal; //automatically initialized
  77. -  std::setlocale(LC_NUMERIC, "en_US.utf8");
  78. +  locale_t saved_locale;
  79. +  locale_t posix_locale;
  80. +
  81. +  /*
  82. +   * Use POSIX locale because the code below uses functions which
  83. +   * parse floating-poing values using locale-specific functions
  84. +   */
  85. +  posix_locale = rov_get_posix_localeobj();
  86. +  saved_locale = uselocale(posix_locale);
  87.  #endif
  88.    T_Bool bOk = true;
  89.    const string sToken = C_RovTool::strParse (_rsString, RDF_SEPARATOR);
  90. @@ -718,7 +725,7 @@ RINLINE T_Bool g_ReadNumericalValueFromString (
  91.  
  92.    } // end if (!bOk)
  93.   #ifdef JNA
  94. -  locale::global(actualLocal);
  95. +  (void)uselocale(saved_locale);
  96.  #endif
  97.    return(bOk);
  98.  }    // end of readNumericalValueFromString
  99. @@ -764,8 +771,15 @@ RINLINE T_Bool writeNumericalValueToString (
  100.                                             )
  101.  {
  102.  #ifdef JNA
  103. -  std::locale actualLocal; //automatically initialized
  104. -  std::setlocale(LC_NUMERIC, "en_US.utf8");
  105. +  locale_t saved_locale;
  106. +  locale_t posix_locale;
  107. +
  108. +  /*
  109. +   * Use POSIX locale because the code below uses functions which
  110. +   * parse floating-poing values using locale-specific functions
  111. +   */
  112. +  posix_locale = rov_get_posix_localeobj();
  113. +  saved_locale = uselocale(posix_locale);
  114.  #endif
  115.    register T_Bool bOk = true;
  116.    if ( _pValue != NULL )
  117. @@ -827,7 +841,7 @@ RINLINE T_Bool writeNumericalValueToString (
  118.    }   // end if (_pValue != NULL)
  119.    _rsString += RDF_SEPARATOR;
  120.  #ifdef JNA
  121. -  locale::global(actualLocal);
  122. +  (void)uselocale(saved_locale);
  123.  #endif
  124.    return(bOk);
  125.  }    // end of writeNumericalValueToString
  126. diff --git a/Rdc/RdsUnit.h b/Rdc/RdsUnit.h
  127. index 11c8e38..1e3f903 100755
  128. --- a/Rdc/RdsUnit.h
  129. +++ b/Rdc/RdsUnit.h
  130. @@ -559,14 +559,21 @@ public:
  131.  //******************************************************************************
  132.  RINLINE T_Bool  C_RdsUnitSize::convertString2Double(const string &_anyStr, T_Double64 & _anyDouble)
  133.  {
  134. - #ifdef JNA
  135. -    std::locale actualLocal; //automatically initialized
  136. -    std::setlocale(LC_NUMERIC, "en_US.utf8");
  137. +#ifdef JNA
  138. +    locale_t saved_locale;
  139. +    locale_t posix_locale;
  140. +
  141. +    /*
  142. +     * Use POSIX locale because the code below uses functions which
  143. +     * parse floating-poing values using locale-specific functions
  144. +     */
  145. +    posix_locale = rov_get_posix_localeobj();
  146. +    saved_locale = uselocale(posix_locale);
  147.  #endif
  148.      T_String stopStr = (T_String) _anyStr.c_str();
  149.      _anyDouble = strtod(stopStr, & stopStr);
  150.  #ifdef JNA
  151. -    locale::global(actualLocal);
  152. +    (void)uselocale(saved_locale);
  153.  #endif
  154.      return true;
  155.  }    // end C_RdsUnitSize::convertString2Double
  156. diff --git a/Rds/RdsLib/RdsDataStream.cpp b/Rds/RdsLib/RdsDataStream.cpp
  157. index fedff82..b91d504 100755
  158. --- a/Rds/RdsLib/RdsDataStream.cpp
  159. +++ b/Rds/RdsLib/RdsDataStream.cpp
  160. @@ -847,10 +847,15 @@ RINLINE T_Bool C_RdsDataStream::readStream(C_RdsLoadFlags &_roLoadFlags,
  161.          const T_Bool _bAutoNvRamInit /* = false */,
  162.          const T_Name _SRamFileName /* = NULL */) {
  163.      T_Bool bOk = true;
  164. +    locale_t saved_locale;
  165. +    locale_t posix_locale;
  166.  
  167. -    // Set LC_NUMERIC to C because the real values are written as 123.456
  168. -    std::string oldLocale(setlocale(LC_NUMERIC, nullptr));
  169. -    setlocale(LC_NUMERIC, "C");
  170. +    /*
  171. +     * Use POSIX locale because the code below uses functions which
  172. +     * parse floating-poing values using locale-specific functions
  173. +     */
  174. +    posix_locale = rov_get_posix_localeobj();
  175. +    saved_locale = uselocale(posix_locale);
  176.  
  177.      if (0 == _pRdsAbsDirectory)
  178.          _pRdsAbsDirectory = this;
  179. @@ -975,7 +980,7 @@ RINLINE T_Bool C_RdsDataStream::readStream(C_RdsLoadFlags &_roLoadFlags,
  180.                                          m_poRdsLocalClientID, _fileName,
  181.                                          onlyOnRdf.c_str(),
  182.                                          m_sActFileName.c_str());
  183. -                                setlocale(LC_NUMERIC, oldLocale.c_str());
  184. +                                (void)uselocale(saved_locale);
  185.                                  bOk = false;
  186.                                  return (bOk);
  187.                              }
  188. @@ -1024,7 +1029,7 @@ RINLINE T_Bool C_RdsDataStream::readStream(C_RdsLoadFlags &_roLoadFlags,
  189.              poRdsError->m_iLine);
  190.      assert(checkTree(_pRdsAbsDirectory));
  191.  // delete[] szBuffer;
  192. -    setlocale(LC_NUMERIC, oldLocale.c_str());
  193. +    (void)uselocale(saved_locale);
  194.      return (bOk);
  195.  } // end of C_RdsDataStream::readStream
  196.  
  197. diff --git a/Rds/RdsLib/RdsReal.cpp b/Rds/RdsLib/RdsReal.cpp
  198. index c8f28b2..8f5e72e 100755
  199. --- a/Rds/RdsLib/RdsReal.cpp
  200. +++ b/Rds/RdsLib/RdsReal.cpp
  201. @@ -44,6 +44,8 @@
  202.  #include "RdsClientLocal.h"
  203.  #include "DExtMath.hpp"
  204.  
  205. +#include <locale.h>
  206. +
  207.  
  208.  #define RINLINE
  209.  
  210. @@ -1539,10 +1541,15 @@ RINLINE T_Bool C_RdsUnit::readUnitSizeFile(const string &_path)
  211.  {
  212.    T_Bool isOK = true;
  213.  
  214. -  char savedLocale[32];
  215. -  /* Get the name of the current locale.  */
  216. -  strncpy(savedLocale, setlocale (LC_NUMERIC, NULL), 32);
  217. -  setlocale(LC_NUMERIC, "C");
  218. +  locale_t saved_locale;
  219. +  locale_t posix_locale;
  220. +
  221. +  /*
  222. +   * Use POSIX locale because the code below uses functions which
  223. +   * parse floating-poing values using locale-specific functions
  224. +   */
  225. +  posix_locale = rov_get_posix_localeobj();
  226. +  saved_locale = uselocale(posix_locale);
  227.  
  228.    string completeFileName(SIZE_AND_UNIT_DIR);
  229.    if ( !_path.empty() )
  230. @@ -1617,7 +1624,9 @@ RINLINE T_Bool C_RdsUnit::readUnitSizeFile(const string &_path)
  231.      poSuRdsError->perrorLog (errorMsg.str().c_str());
  232.      isOK = false;
  233.    } // end else !inStream
  234. -  setlocale(LC_NUMERIC, savedLocale);
  235. +  
  236. +  (void)uselocale(saved_locale);
  237. +
  238.    return(isOK);
  239.  } // end of method C_RdsUnit::readUnitSizeFile

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at