Explorar o código

HPCC-13941 Make unicode conversions thread safe.

Unicode page conversions of the same code page, used the same
converter instance and were thread unsafe.
Use a codepage table per thread (using a thread variable).

Signed-off-by: Jake Smith <jake.smith@lexisnexis.com>
Jake Smith %!s(int64=10) %!d(string=hai) anos
pai
achega
c86186cf91
Modificáronse 1 ficheiros con 12 adicións e 9 borrados
  1. 12 9
      rtl/eclrtl/eclrtl.cpp

+ 12 - 9
rtl/eclrtl/eclrtl.cpp

@@ -307,23 +307,26 @@ private:
 };
 
 typedef MapStringTo<RTLUnicodeConverter, char const *> MapStrToUnicodeConverter;
-MapStrToUnicodeConverter *unicodeConverterMap;
+static __thread MapStrToUnicodeConverter *unicodeConverterMap = NULL;
+static __thread ThreadTermFunc prevThreadTerminator = NULL;
 CriticalSection ucmCrit;
 
-MODULE_INIT(INIT_PRIORITY_STANDARD)
-{
-    unicodeConverterMap = new MapStrToUnicodeConverter;
-    return true;
-}
-MODULE_EXIT()
+static void clearUnicodeConverterMap()
 {
     delete unicodeConverterMap;
+    if (prevThreadTerminator)
+        (*prevThreadTerminator)();
 }
 
-
 RTLUnicodeConverter * queryRTLUnicodeConverter(char const * codepage)
 {
-    CriticalBlock b(ucmCrit);
+    if (!unicodeConverterMap) // NB: one per thread, so no contention
+    {
+        unicodeConverterMap = new MapStrToUnicodeConverter(GetCurrentThreadId());
+        // Use thread terminator hook to clear them up on thread exit.
+        // NB: May need to revisit if not on a jlib Thread.
+        prevThreadTerminator = addThreadTermFunc(clearUnicodeConverterMap);
+    }
     RTLUnicodeConverter * conv = unicodeConverterMap->getValue(codepage);
     if(!conv)
     {