]> granicus.if.org Git - icu/commitdiff
ICU-10051 Mutexes: introduce UInitOnce; remove UMTX_CHECK; replace all uses of UMTX_C...
authorAndy Heninger <andy.heninger@gmail.com>
Sat, 1 Jun 2013 03:37:16 +0000 (03:37 +0000)
committerAndy Heninger <andy.heninger@gmail.com>
Sat, 1 Jun 2013 03:37:16 +0000 (03:37 +0000)
X-SVN-Rev: 33788

47 files changed:
icu4c/source/common/brkiter.cpp
icu4c/source/common/common.vcxproj
icu4c/source/common/dictionarydata.cpp
icu4c/source/common/dictionarydata.h
icu4c/source/common/locavailable.cpp
icu4c/source/common/mutex.cpp
icu4c/source/common/mutex.h
icu4c/source/common/normalizer2impl.cpp
icu4c/source/common/normalizer2impl.h
icu4c/source/common/putilimp.h
icu4c/source/common/rbbi.cpp
icu4c/source/common/rbbidata.h
icu4c/source/common/resbund.cpp
icu4c/source/common/stringpiece.cpp
icu4c/source/common/ucln_cmn.c
icu4c/source/common/ucnv_bld.cpp
icu4c/source/common/ucnv_io.cpp
icu4c/source/common/udata.cpp
icu4c/source/common/umutex.cpp
icu4c/source/common/umutex.h
icu4c/source/common/unames.cpp
icu4c/source/common/unicode/locid.h
icu4c/source/common/unicode/resbund.h
icu4c/source/common/unicode/stringpiece.h
icu4c/source/common/unicode/uclean.h
icu4c/source/common/unicode/uniset.h
icu4c/source/common/uniset_props.cpp
icu4c/source/common/unistr.cpp
icu4c/source/common/uresbund.cpp
icu4c/source/common/usprep.cpp
icu4c/source/common/utrie2.cpp
icu4c/source/config/mh-linux
icu4c/source/io/io.vcxproj
icu4c/source/io/locbund.cpp
icu4c/source/samples/cal/cal.vcxproj
icu4c/source/test/cintltst/cintltst.c
icu4c/source/test/cintltst/cintltst.vcxproj
icu4c/source/test/cintltst/hpmufn.c
icu4c/source/test/intltest/intltest.vcxproj
icu4c/source/tools/ctestfw/ctest.c
icu4c/source/tools/genbrk/genbrk.vcxproj
icu4c/source/tools/gencfu/gencfu.vcxproj
icu4c/source/tools/gencnval/gencnval.vcxproj
icu4c/source/tools/gennorm2/gennorm2.vcxproj
icu4c/source/tools/gensprep/gensprep.vcxproj
icu4c/source/tools/makeconv/makeconv.vcxproj
icu4c/source/tools/toolutil/toolutil.vcxproj

index 90ba78d173186bf9f693710fe51f380173eff759..9744a2cfd3f600ef9ac7429b96721f7a00d92eca 100644 (file)
@@ -1,6 +1,6 @@
 /*
 *******************************************************************************
-* Copyright (C) 1997-2011, International Business Machines Corporation and
+* Copyright (C) 1997-2013, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 *
@@ -271,6 +271,7 @@ U_NAMESPACE_END
 // defined in ucln_cmn.h
 
 static icu::ICULocaleService* gService = NULL;
+static UInitOnce gInitOnce;
 
 /**
  * Release all static memory held by breakiterator.
@@ -282,40 +283,33 @@ static UBool U_CALLCONV breakiterator_cleanup(void) {
         delete gService;
         gService = NULL;
     }
+    gInitOnce.reset();
 #endif
     return TRUE;
 }
 U_CDECL_END
 U_NAMESPACE_BEGIN
 
+static void U_CALLCONV 
+initService(void) {
+    gService = new ICUBreakIteratorService();
+    ucln_common_registerCleanup(UCLN_COMMON_BREAKITERATOR, breakiterator_cleanup);
+}
+
 static ICULocaleService*
 getService(void)
 {
-    UBool needsInit;
-    UMTX_CHECK(NULL, (UBool)(gService == NULL), needsInit);
-
-    if (needsInit) {
-        ICULocaleService  *tService = new ICUBreakIteratorService();
-        umtx_lock(NULL);
-        if (gService == NULL) {
-            gService = tService;
-            tService = NULL;
-            ucln_common_registerCleanup(UCLN_COMMON_BREAKITERATOR, breakiterator_cleanup);
-        }
-        umtx_unlock(NULL);
-        delete tService;
-    }
+    umtx_initOnce(gInitOnce, &initService);
     return gService;
 }
 
+
 // -------------------------------------
 
 static inline UBool
 hasService(void)
 {
-    UBool retVal;
-    UMTX_CHECK(NULL, gService != NULL, retVal);
-    return retVal;
+    return !gInitOnce.isReset() && getService() != NULL;
 }
 
 // -------------------------------------
index 806b0c659321060a00061db558ccbbbc0a4b00a0..4c35ff8a9c7b6f3e5e1732c3d4041b5d07e48f42 100644 (file)
@@ -90,7 +90,7 @@
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x86\Release/common.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x86\Debug/common.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>\r
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Release/common.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Debug/common.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>\r
     <ClCompile Include="ubidiln.c" />\r
     <ClCompile Include="ubidiwrt.c" />\r
     <ClCompile Include="ushape.cpp" />\r
-    <ClCompile Include="brkeng.cpp" />\r
-    <ClCompile Include="brkiter.cpp" />\r
+    <ClCompile Include="brkeng.cpp">\r
+    </ClCompile>\r
+    <ClCompile Include="brkiter.cpp">\r
+    </ClCompile>\r
     <ClCompile Include="dictbe.cpp" />\r
-    <ClCompile Include="rbbi.cpp" />\r
-    <ClCompile Include="rbbidata.cpp" />\r
+    <ClCompile Include="rbbi.cpp">\r
+    </ClCompile>\r
+    <ClCompile Include="rbbidata.cpp">\r
+    </ClCompile>\r
     <ClCompile Include="rbbinode.cpp" />\r
-    <ClCompile Include="rbbirb.cpp" />\r
+    <ClCompile Include="rbbirb.cpp">\r
+    </ClCompile>\r
     <ClCompile Include="rbbiscan.cpp" />\r
     <ClCompile Include="rbbisetb.cpp" />\r
-    <ClCompile Include="rbbistbl.cpp" />\r
-    <ClCompile Include="rbbitblb.cpp" />\r
+    <ClCompile Include="rbbistbl.cpp">\r
+    </ClCompile>\r
+    <ClCompile Include="rbbitblb.cpp">\r
+    </ClCompile>\r
     <ClCompile Include="dictionarydata.cpp" />\r
     <ClCompile Include="ubrk.cpp" />\r
     <ClCompile Include="ucol_swp.cpp">\r
       <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>\r
       <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>\r
     </ClCompile>\r
-    <ClCompile Include="mutex.cpp" />\r
+    <ClCompile Include="mutex.cpp">\r
+    </ClCompile>\r
     <ClCompile Include="putil.cpp">\r
       <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>\r
       <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>\r
     </ClCompile>\r
     <ClCompile Include="ucnv.c" />\r
     <ClCompile Include="ucnv2022.cpp" />\r
-    <ClCompile Include="ucnv_bld.cpp" />\r
+    <ClCompile Include="ucnv_bld.cpp">\r
+    </ClCompile>\r
     <ClCompile Include="ucnv_cb.c" />\r
     <ClCompile Include="ucnv_cnv.c" />\r
     <ClCompile Include="ucnv_ct.c" />\r
     <ClCompile Include="ucnv_err.c" />\r
     <ClCompile Include="ucnv_ext.cpp" />\r
-    <ClCompile Include="ucnv_io.cpp" />\r
+    <ClCompile Include="ucnv_io.cpp">\r
+    </ClCompile>\r
     <ClCompile Include="ucnv_lmb.c" />\r
     <ClCompile Include="ucnv_set.c" />\r
     <ClCompile Include="ucnv_u16.c" />\r
     <ClCompile Include="ucnvlat1.c" />\r
     <ClCompile Include="ucnvmbcs.c" />\r
     <ClCompile Include="ucnvscsu.c" />\r
-    <ClCompile Include="ucnvsel.cpp" />\r
+    <ClCompile Include="ucnvsel.cpp">\r
+    </ClCompile>\r
     <ClCompile Include="cmemory.c" />\r
     <ClCompile Include="ucln_cmn.c">\r
       <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>\r
     <ClCompile Include="punycode.cpp" />\r
     <ClCompile Include="uidna.cpp" />\r
     <ClCompile Include="uts46.cpp" />\r
-    <ClCompile Include="locavailable.cpp" />\r
+    <ClCompile Include="locavailable.cpp">\r
+    </ClCompile>\r
     <ClCompile Include="locbased.cpp" />\r
     <ClCompile Include="locdispnames.cpp" />\r
-    <ClCompile Include="locid.cpp" />\r
+    <ClCompile Include="locid.cpp">\r
+    </ClCompile>\r
     <ClCompile Include="loclikely.cpp" />\r
     <ClCompile Include="locresdata.cpp" />\r
-    <ClCompile Include="locutil.cpp" />\r
-    <ClCompile Include="resbund.cpp" />\r
+    <ClCompile Include="locutil.cpp">\r
+    </ClCompile>\r
+    <ClCompile Include="resbund.cpp">\r
+    </ClCompile>\r
     <ClCompile Include="resbund_cnv.cpp" />\r
     <ClCompile Include="ucat.c" />\r
     <ClCompile Include="uloc.cpp" />\r
     <ClCompile Include="ures_cnv.c" />\r
     <ClCompile Include="uresbund.cpp" />\r
     <ClCompile Include="uresdata.c" />\r
-    <ClCompile Include="caniter.cpp" />\r
+    <ClCompile Include="caniter.cpp">\r
+    </ClCompile>\r
     <ClCompile Include="filterednormalizer2.cpp" />\r
-    <ClCompile Include="normalizer2.cpp" />\r
-    <ClCompile Include="normalizer2impl.cpp" />\r
-    <ClCompile Include="normlzr.cpp" />\r
+    <ClCompile Include="normalizer2.cpp">\r
+    </ClCompile>\r
+    <ClCompile Include="normalizer2impl.cpp">\r
+    </ClCompile>\r
+    <ClCompile Include="normlzr.cpp">\r
+    </ClCompile>\r
     <ClCompile Include="unorm.cpp" />\r
     <ClCompile Include="unorm_it.c" />\r
     <ClCompile Include="unormcmp.cpp" />\r
     <ClCompile Include="bmpset.cpp" />\r
     <ClCompile Include="patternprops.cpp" />\r
-    <ClCompile Include="propname.cpp" />\r
+    <ClCompile Include="propname.cpp">\r
+    </ClCompile>\r
     <ClCompile Include="ruleiter.cpp" />\r
-    <ClCompile Include="ucase.cpp" />\r
+    <ClCompile Include="ucase.cpp">\r
+    </ClCompile>\r
     <ClCompile Include="uchar.c" />\r
     <ClCompile Include="unames.cpp" />\r
     <ClCompile Include="unifilt.cpp" />\r
     <ClCompile Include="uset_props.cpp" />\r
     <ClCompile Include="usetiter.cpp" />\r
     <ClCompile Include="icuplug.c" />\r
-    <ClCompile Include="serv.cpp" />\r
-    <ClCompile Include="servlk.cpp" />\r
-    <ClCompile Include="servlkf.cpp" />\r
-    <ClCompile Include="servls.cpp" />\r
-    <ClCompile Include="servnotf.cpp" />\r
-    <ClCompile Include="servrbf.cpp" />\r
-    <ClCompile Include="servslkf.cpp" />\r
+    <ClCompile Include="serv.cpp">\r
+    </ClCompile>\r
+    <ClCompile Include="servlk.cpp">\r
+    </ClCompile>\r
+    <ClCompile Include="servlkf.cpp">\r
+    </ClCompile>\r
+    <ClCompile Include="servls.cpp">\r
+    </ClCompile>\r
+    <ClCompile Include="servnotf.cpp">\r
+    </ClCompile>\r
+    <ClCompile Include="servrbf.cpp">\r
+    </ClCompile>\r
+    <ClCompile Include="servslkf.cpp">\r
+    </ClCompile>\r
     <ClCompile Include="usprep.cpp" />\r
     <ClCompile Include="appendable.cpp" />\r
     <ClCompile Include="bytestream.cpp" />\r
     <ClCompile Include="ustrtrns.cpp" />\r
     <ClCompile Include="utext.cpp" />\r
     <ClCompile Include="utf_impl.c" />\r
-    <ClCompile Include="listformatter.cpp" />\r
+    <ClCompile Include="listformatter.cpp">\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <CustomBuild Include="unicode\ubidi.h">\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
   <ImportGroup Label="ExtensionTargets">\r
   </ImportGroup>\r
-</Project>
\ No newline at end of file
+</Project>\r
index a29e5090dd0970a41b3721dc77f3bf7fc326a834..039871b5be8a1c145beb22df3c037506a4dd700f 100644 (file)
@@ -1,6 +1,6 @@
 /*
 *******************************************************************************
-* Copyright (C) 2012, International Business Machines
+* Copyright (C) 2013, International Business Machines
 * Corporation and others.  All Rights Reserved.
 *******************************************************************************
 * dictionarydata.h
 
 U_NAMESPACE_BEGIN
 
-#ifndef CYGWINMSVC /* On Cygwin/MSVC, the error redefinition of symbols occurs.*/
-const int32_t DictionaryData::TRIE_TYPE_BYTES;
-const int32_t DictionaryData::TRIE_TYPE_UCHARS;
-#endif
+const int32_t  DictionaryData::TRIE_TYPE_BYTES = 0;
+const int32_t  DictionaryData::TRIE_TYPE_UCHARS = 1;
+const int32_t  DictionaryData::TRIE_TYPE_MASK = 7;
+const int32_t  DictionaryData::TRIE_HAS_VALUES = 8;
 
+const int32_t  DictionaryData::TRANSFORM_NONE = 0;
+const int32_t  DictionaryData::TRANSFORM_TYPE_OFFSET = 0x1000000;
+const int32_t  DictionaryData::TRANSFORM_TYPE_MASK = 0x7f000000;
+const int32_t  DictionaryData::TRANSFORM_OFFSET_MASK = 0x1fffff;
+    
 DictionaryMatcher::~DictionaryMatcher() {
 }
 
index ad4c9284768d5f8a36b958774239baebd370e11f..36b31d06a846bcd07561f7b9565923665d410b40 100644 (file)
@@ -1,6 +1,6 @@
 /*
 *******************************************************************************
-* Copyright (C) 2012, International Business Machines
+* Copyright (C) 2013, International Business Machines
 * Corporation and others.  All Rights Reserved.
 *******************************************************************************
 * dictionarydata.h
@@ -29,15 +29,15 @@ class BytesTrie;
 
 class U_COMMON_API DictionaryData : public UMemory {
 public:
-    static const int32_t TRIE_TYPE_BYTES = 0;
-    static const int32_t TRIE_TYPE_UCHARS = 1;
-    static const int32_t TRIE_TYPE_MASK = 7;
-    static const int32_t TRIE_HAS_VALUES = 8;
-
-    static const int32_t TRANSFORM_NONE = 0;
-    static const int32_t TRANSFORM_TYPE_OFFSET = 0x1000000;
-    static const int32_t TRANSFORM_TYPE_MASK = 0x7f000000;
-    static const int32_t TRANSFORM_OFFSET_MASK = 0x1fffff;
+    static const int32_t TRIE_TYPE_BYTES; // = 0;
+    static const int32_t TRIE_TYPE_UCHARS; // = 1;
+    static const int32_t TRIE_TYPE_MASK; // = 7;
+    static const int32_t TRIE_HAS_VALUES; // = 8;
+
+    static const int32_t TRANSFORM_NONE; // = 0;
+    static const int32_t TRANSFORM_TYPE_OFFSET; // = 0x1000000;
+    static const int32_t TRANSFORM_TYPE_MASK; // = 0x7f000000;
+    static const int32_t TRANSFORM_OFFSET_MASK; // = 0x1fffff;
 
     enum {
         // Byte offsets from the start of the data, after the generic header.
index c8baf753d6b5ba9f5d0174e55db26a99119eada3..62cdf972cba9e6c51ae3a507adec4e3329d83e3d 100644 (file)
@@ -1,7 +1,7 @@
 /*
 *******************************************************************************
 *
-*   Copyright (C) 1997-2011, International Business Machines
+*   Copyright (C) 1997-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
@@ -23,6 +23,7 @@
 #include "unicode/ures.h"
 #include "cmemory.h"
 #include "ucln_cmn.h"
+#include "uassert.h"
 #include "umutex.h"
 #include "uresimp.h"
 
@@ -30,6 +31,7 @@
 
 static icu::Locale*  availableLocaleList = NULL;
 static int32_t  availableLocaleListCount;
+static UInitOnce gInitOnce = U_INITONCE_INITIALIZER;
 
 U_CDECL_BEGIN
 
@@ -42,6 +44,7 @@ static UBool U_CALLCONV locale_available_cleanup(void)
         availableLocaleList = NULL;
     }
     availableLocaleListCount = 0;
+    gInitOnce.reset();
 
     return TRUE;
 }
@@ -50,40 +53,29 @@ U_CDECL_END
 
 U_NAMESPACE_BEGIN
 
+void U_CALLCONV locale_available_init() {
+    // This function is a friend of class Locale.
+    // This function is only invoked via umtx_initOnce().
+    
+    // for now, there is a hardcoded list, so just walk through that list and set it up.
+    //  Note: this function is a friend of class Locale.
+    availableLocaleListCount = uloc_countAvailable();
+    if(availableLocaleListCount) {
+       availableLocaleList = new Locale[availableLocaleListCount];
+    }
+    if (availableLocaleList == NULL) {
+        availableLocaleListCount= 0;
+    }
+    for (int32_t locCount=availableLocaleListCount-1; locCount>=0; --locCount) {
+        availableLocaleList[locCount].setFromPOSIXID(uloc_getAvailable(locCount));
+    }
+    ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE, locale_available_cleanup);
+}
+
 const Locale* U_EXPORT2
 Locale::getAvailableLocales(int32_t& count)
 {
-    // for now, there is a hardcoded list, so just walk through that list and set it up.
-    UBool needInit;
-    UMTX_CHECK(NULL, availableLocaleList == NULL, needInit);
-
-    if (needInit) {
-        int32_t locCount = uloc_countAvailable();
-        Locale *newLocaleList = 0;
-        if(locCount) {
-           newLocaleList = new Locale[locCount];
-        }
-        if (newLocaleList == NULL) {
-            count = 0;
-            return NULL;
-        }
-
-        count = locCount;
-
-        while(--locCount >= 0) {
-            newLocaleList[locCount].setFromPOSIXID(uloc_getAvailable(locCount));
-        }
-
-        umtx_lock(NULL);
-        if(availableLocaleList == 0) {
-            availableLocaleListCount = count;
-            availableLocaleList = newLocaleList;
-            newLocaleList = NULL;
-            ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE, locale_available_cleanup);
-        }
-        umtx_unlock(NULL);
-        delete []newLocaleList;
-    }
+    umtx_initOnce(gInitOnce, &locale_available_init);
     count = availableLocaleListCount;
     return availableLocaleList;
 }
@@ -104,6 +96,7 @@ static const char _kIndexTag[]        = "InstalledLocales";
 
 static char** _installedLocales = NULL;
 static int32_t _installedLocalesCount = 0;
+static UInitOnce _installedLocalesInitOnce;
 
 /* ### Get available **************************************************/
 
@@ -115,57 +108,51 @@ static UBool U_CALLCONV uloc_cleanup(void) {
         _installedLocales = NULL;
 
         _installedLocalesCount = 0;
+        _installedLocalesInitOnce.reset();
 
         uprv_free(temp);
     }
     return TRUE;
 }
 
-static void _load_installedLocales()
-{
-    UBool   localesLoaded;
+// Load Installed Locales. This function will be called exactly once
+//   via the initOnce mechanism.
 
-    UMTX_CHECK(NULL, _installedLocales != NULL, localesLoaded);
+static void U_CALLCONV loadInstalledLocales() {
+    UResourceBundle *indexLocale = NULL;
+    UResourceBundle installed;
+    UErrorCode status = U_ZERO_ERROR;
+    int32_t i = 0;
+    int32_t localeCount;
     
-    if (localesLoaded == FALSE) {
-        UResourceBundle *indexLocale = NULL;
-        UResourceBundle installed;
-        UErrorCode status = U_ZERO_ERROR;
-        char ** temp;
-        int32_t i = 0;
-        int32_t localeCount;
-        
-        ures_initStackObject(&installed);
-        indexLocale = ures_openDirect(NULL, _kIndexLocaleName, &status);
-        ures_getByKey(indexLocale, _kIndexTag, &installed, &status);
-        
-        if(U_SUCCESS(status)) {
-            localeCount = ures_getSize(&installed);
-            temp = (char **) uprv_malloc(sizeof(char*) * (localeCount+1));
-            /* Check for null pointer */
-            if (temp != NULL) {
-                ures_resetIterator(&installed);
-                while(ures_hasNext(&installed)) {
-                    ures_getNextString(&installed, NULL, (const char **)&temp[i++], &status);
-                }
-                temp[i] = NULL;
-
-                umtx_lock(NULL);
-                if (_installedLocales == NULL)
-                {
-                    _installedLocalesCount = localeCount;
-                    _installedLocales = temp;
-                    temp = NULL;
-                    ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
-                } 
-                umtx_unlock(NULL);
-
-                uprv_free(temp);
+    U_ASSERT(_installedLocales == NULL);
+    U_ASSERT(_installedLocalesCount == 0);
+
+    _installedLocalesCount = 0;
+    ures_initStackObject(&installed);
+    indexLocale = ures_openDirect(NULL, _kIndexLocaleName, &status);
+    ures_getByKey(indexLocale, _kIndexTag, &installed, &status);
+    
+    if(U_SUCCESS(status)) {
+        localeCount = ures_getSize(&installed);
+        _installedLocales = (char **) uprv_malloc(sizeof(char*) * (localeCount+1));
+        if (_installedLocales != NULL) {
+            ures_resetIterator(&installed);
+            while(ures_hasNext(&installed)) {
+                ures_getNextString(&installed, NULL, (const char **)&_installedLocales[i++], &status);
             }
+            _installedLocales[i] = NULL;
+            _installedLocalesCount = localeCount;
+            ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
         }
-        ures_close(&installed);
-        ures_close(indexLocale);
     }
+    ures_close(&installed);
+    ures_close(indexLocale);
+}
+
+static void _load_installedLocales()
+{
+    umtx_initOnce(_installedLocalesInitOnce, &loadInstalledLocales);
 }
 
 U_CAPI const char* U_EXPORT2
index e1e502d4ad90974fbf87e0b47e4dae2a814c4927..1742ab57e3ee48de88fb2b8e6938897728e326c0 100644 (file)
@@ -1,7 +1,7 @@
 /*
 *******************************************************************************
 *
-*   Copyright (C) 2008-2011, International Business Machines
+*   Copyright (C) 2008-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
 U_NAMESPACE_BEGIN
 
 void *SimpleSingleton::getInstance(InstantiatorFn *instantiator, const void *context,
-                                   void *&duplicate,
                                    UErrorCode &errorCode) {
-    duplicate=NULL;
     if(U_FAILURE(errorCode)) {
         return NULL;
     }
-    // TODO: With atomicops.h: void *instance = (void*)Acquire_Load(&fInstance);
-    //       and remove UMTX_ACQUIRE_BARRIER below.
-    void *instance=ANNOTATE_UNPROTECTED_READ(fInstance);
-    UMTX_ACQUIRE_BARRIER;
-    ANNOTATE_HAPPENS_AFTER(&fInstance);
-    if(instance!=NULL) {
-        return instance;
+    if (umtx_loadAcquire(fInitOnce.fState) == 2) {
+        return fInstance;
     }
-
-    // Attempt to create the instance.
-    // If a race occurs, then the losing thread will assign its new instance
-    // to the "duplicate" parameter, and the caller deletes it.
-    instance=instantiator(context, errorCode);
-    UMTX_RELEASE_BARRIER;  // Release-barrier before fInstance=instance;
-    Mutex mutex;
-    if(fInstance==NULL && U_SUCCESS(errorCode)) {
-        U_ASSERT(instance!=NULL);
-        ANNOTATE_HAPPENS_BEFORE(&fInstance);
-        // TODO: With atomicops.h: Release_Store(&fInstance, (AtomicWord)instance);
-        //       and remove UMTX_RELEASE_BARRIER above.
-        fInstance=instance;
-    } else {
-        duplicate=instance;
+    if (umtx_initImplPreInit(fInitOnce)) {
+        fInstance = instantiator(context, errorCode);
+        umtx_initImplPostInit(fInitOnce, fInstance != NULL);
     }
     return fInstance;
 }
 
+
 /*
  * Three states:
  *
  * Initial state: Instance creation not attempted yet.
  * fInstance=NULL && U_SUCCESS(fErrorCode)
  *
- * Instance creation succeeded:
+ * Instance creation run & succeeded:
  * fInstance!=NULL && U_SUCCESS(fErrorCode)
  *
- * Instance creation failed:
+ * Instance creation failed:
  * fInstance=NULL && U_FAILURE(fErrorCode)
  * We will not attempt again to create the instance.
  *
- * fInstance changes at most once.
- * fErrorCode changes at most twice (intial->failed->succeeded).
+ * The instantiator function will be called only once, whether it succeeds or fails.
+ * The controlling state is maintained by the UInitOnce object, not by
+ *    fInstance and fErrorCode.
+ * The values of fInstance and fErrorCode must only be set between pre and post init(),
+ *    where they are in a controlled memory environment.
  */
 void *TriStateSingleton::getInstance(InstantiatorFn *instantiator, const void *context,
-                                     void *&duplicate,
                                      UErrorCode &errorCode) {
-    duplicate=NULL;
     if(U_FAILURE(errorCode)) {
         return NULL;
     }
-    // TODO: With atomicops.h: void *instance = (void*)Acquire_Load(&fInstance);
-    //       and remove UMTX_ACQUIRE_BARRIER below.
-    void *instance=ANNOTATE_UNPROTECTED_READ(fInstance);
-    UMTX_ACQUIRE_BARRIER;
-    ANNOTATE_HAPPENS_AFTER(&fInstance);
-    if(instance!=NULL) {
-        // instance was created
-        return instance;
+    if (umtx_loadAcquire(fInitOnce.fState) == 2) {
+        errorCode = fErrorCode;
+        return fInstance;
     }
-
-    // The read access to fErrorCode is thread-unsafe, but harmless because
-    // at worst multiple threads race to each create a new instance,
-    // and all losing threads delete their duplicates.
-    UErrorCode localErrorCode=ANNOTATE_UNPROTECTED_READ(fErrorCode);
-    if(U_FAILURE(localErrorCode)) {
-        // instance creation failed
-        errorCode=localErrorCode;
-        return NULL;
-    }
-
-    // First attempt to create the instance.
-    // If a race occurs, then the losing thread will assign its new instance
-    // to the "duplicate" parameter, and the caller deletes it.
-    instance=instantiator(context, errorCode);
-    UMTX_RELEASE_BARRIER;  // Release-barrier before fInstance=instance;
-    Mutex mutex;
-    if(fInstance==NULL && U_SUCCESS(errorCode)) {
-        // instance creation newly succeeded
-        U_ASSERT(instance!=NULL);
-        ANNOTATE_HAPPENS_BEFORE(&fInstance);
-        // TODO: With atomicops.h: Release_Store(&fInstance, (AtomicWord)instance);
-        //       and remove UMTX_RELEASE_BARRIER above.
-        fInstance=instance;
-        // Set fErrorCode on the off-chance that a previous instance creation failed.
-        fErrorCode=errorCode;
-        // Completed state transition: initial->succeeded, or failed->succeeded.
-    } else {
-        // Record a duplicate if we lost the race, or
-        // if we got an instance but its creation failed anyway.
-        duplicate=instance;
-        if(fInstance==NULL && U_SUCCESS(fErrorCode) && U_FAILURE(errorCode)) {
-            // instance creation newly failed
-            fErrorCode=errorCode;
-            // Completed state transition: initial->failed.
-        }
+    if (umtx_initImplPreInit(fInitOnce)) {
+        errorCode = U_ZERO_ERROR;
+        fInstance = instantiator(context, errorCode);
+        fErrorCode = errorCode;
+        umtx_initImplPostInit(fInitOnce, TRUE);
     }
     return fInstance;
 }
 
+
 void TriStateSingleton::reset() {
     fInstance=NULL;
     fErrorCode=U_ZERO_ERROR;
+    fInitOnce.reset();
 }
 
 #if UCONFIG_NO_SERVICE
index af8cd8cb9c24e0a72d149a409f0b72679e456d2a..845a60f59a07e7930e49328da422812861412343 100644 (file)
@@ -1,7 +1,7 @@
 /*
 ******************************************************************************
 *
-*   Copyright (C) 1997-2012, International Business Machines
+*   Copyright (C) 1997-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
@@ -90,27 +90,26 @@ typedef void *InstantiatorFn(const void *context, UErrorCode &errorCode);
  * Define a static SimpleSingleton instance via the STATIC_SIMPLE_SINGLETON macro.
  */
 struct SimpleSingleton {
-    void *fInstance;
+    void      *fInstance;
+    UInitOnce  fInitOnce;
 
     /**
      * Returns the singleton instance, or NULL if it could not be created.
      * Calls the instantiator with the context if the instance has not been
-     * created yet. In a race condition, the duplicate may not be NULL.
-     * The caller must delete the duplicate.
-     * The caller need not initialize the duplicate before the call.
+     * created yet. 
      */
     void *getInstance(InstantiatorFn *instantiator, const void *context,
-                      void *&duplicate,
                       UErrorCode &errorCode);
     /**
      * Resets the fields. The caller must have deleted the singleton instance.
      * Not mutexed.
      * Call this from a cleanup function.
      */
-    void reset() { fInstance=NULL; }
+    void reset() { fInstance=NULL; fInitOnce.reset(); }
 };
 
-#define STATIC_SIMPLE_SINGLETON(name) static SimpleSingleton name={ NULL }
+#define SIMPLE_SINGLETON_INITIALIZER {NULL, U_INITONCE_INITIALIZER}
+#define STATIC_SIMPLE_SINGLETON(name) static SimpleSingleton name = SIMPLE_SINGLETON_INITIALIZER
 
 /**
  * Handy wrapper for a SimpleSingleton.
@@ -127,9 +126,7 @@ public:
     }
     T *getInstance(InstantiatorFn *instantiator, const void *context,
                    UErrorCode &errorCode) {
-        void *duplicate;
-        T *instance=(T *)singleton.getInstance(instantiator, context, duplicate, errorCode);
-        delete (T *)duplicate;
+        T *instance=(T *)singleton.getInstance(instantiator, context, errorCode);
         return instance;
     }
 private:
@@ -143,20 +140,18 @@ private:
  * Define a static TriStateSingleton instance via the STATIC_TRI_STATE_SINGLETON macro.
  */
 struct TriStateSingleton {
-    void *fInstance;
-    UErrorCode fErrorCode;
+    void       *fInstance;
+    UErrorCode  fErrorCode;
+    UInitOnce   fInitOnce;
 
     /**
      * Returns the singleton instance, or NULL if it could not be created.
      * Calls the instantiator with the context if the instance has not been
-     * created yet. In a race condition, the duplicate may not be NULL.
-     * The caller must delete the duplicate.
-     * The caller need not initialize the duplicate before the call.
+     * created yet.
      * The singleton creation is only attempted once. If it fails,
      * the singleton will then always return NULL.
      */
     void *getInstance(InstantiatorFn *instantiator, const void *context,
-                      void *&duplicate,
                       UErrorCode &errorCode);
     /**
      * Resets the fields. The caller must have deleted the singleton instance.
@@ -166,7 +161,7 @@ struct TriStateSingleton {
     void reset();
 };
 
-#define STATIC_TRI_STATE_SINGLETON(name) static TriStateSingleton name={ NULL, U_ZERO_ERROR }
+#define STATIC_TRI_STATE_SINGLETON(name) static TriStateSingleton name={ NULL, U_ZERO_ERROR, U_INITONCE_INITIALIZER }
 
 /**
  * Handy wrapper for a TriStateSingleton.
@@ -183,9 +178,7 @@ public:
     }
     T *getInstance(InstantiatorFn *instantiator, const void *context,
                    UErrorCode &errorCode) {
-        void *duplicate;
-        T *instance=(T *)singleton.getInstance(instantiator, context, duplicate, errorCode);
-        delete (T *)duplicate;
+        T *instance=(T *)singleton.getInstance(instantiator, context, errorCode);
         return instance;
     }
 private:
index 050b58169c7397b44d976acd01b19ad83fd1d90f..72221971051c6bdba339eaad84afd68c139ccfa0 100644 (file)
@@ -1,7 +1,7 @@
 /*
 *******************************************************************************
 *
-*   Copyright (C) 2009-2012, International Business Machines
+*   Copyright (C) 2009-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
@@ -1796,10 +1796,8 @@ public:
     CanonIterDataSingleton(SimpleSingleton &s, Normalizer2Impl &ni, UErrorCode &ec) :
         singleton(s), impl(ni), errorCode(ec) {}
     CanonIterData *getInstance(UErrorCode &errorCode) {
-        void *duplicate;
         CanonIterData *instance=
-            (CanonIterData *)singleton.getInstance(createInstance, this, duplicate, errorCode);
-        delete (CanonIterData *)duplicate;
+            (CanonIterData *)singleton.getInstance(createInstance, this, errorCode);
         return instance;
     }
     static void *createInstance(const void *context, UErrorCode &errorCode);
index f44e8277785a18d78d812b20de6e5700f1818e4e..34d1a25e27309b283562b75a0d4971fbc19a25cc 100644 (file)
@@ -1,7 +1,7 @@
 /*
 *******************************************************************************
 *
-*   Copyright (C) 2009-2011, International Business Machines
+*   Copyright (C) 2009-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
@@ -216,7 +216,7 @@ private:
 class U_COMMON_API Normalizer2Impl : public UMemory {
 public:
     Normalizer2Impl() : memory(NULL), normTrie(NULL) {
-        canonIterDataSingleton.fInstance=NULL;
+        canonIterDataSingleton.reset();
     }
     ~Normalizer2Impl();
 
index a63f223ad390e7ce7113a0622e830b11502455ae..30a17e704f188c56e3deb90d2442987952d0bb6f 100644 (file)
@@ -1,7 +1,7 @@
 /*
 ******************************************************************************
 *
-*   Copyright (C) 1997-2012, International Business Machines
+*   Copyright (C) 1997-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
@@ -183,7 +183,13 @@ typedef size_t uintptr_t;
  */
 #ifdef U_HAVE_GCC_ATOMICS
     /* Use the predefined value. */
-#elif U_GCC_MAJOR_MINOR >= 404
+#elif U_PLATFORM == U_PF_MINGW
+    #define U_HAVE_GCC_ATOMICS 0
+#elif U_GCC_MAJOR_MINOR >= 404 || defined(__clang__)
+    /* TODO: Intel icc and IBM xlc on AIX also support gcc atomics.  (Intel originated them.)
+     *       Add them for these compilers.
+     * Note: Clang sets __GNUC__ defines for version 4.2, so misses the 4.4 test here.
+     */
 #   define U_HAVE_GCC_ATOMICS 1
 #else
 #   define U_HAVE_GCC_ATOMICS 0
@@ -191,6 +197,34 @@ typedef size_t uintptr_t;
 
 /** @} */
 
+
+/**
+ * \def U_HAVE_STD_ATOMICS
+ * Defines whether the standard C++11 <atomic> is available.
+ * @internal
+ */
+#ifdef U_HAVE_STD_ATOMICS
+    /* Use the predefined value. */
+#elif defined(__cplusplus) && __cplusplus>=201103L
+    /* C++11, so we should have atomics, except for specific platforms or compilers. */
+
+#if __clang__ && defined(__apple_build_version__) && __clang_major__==4 && __clang_minor__<=1
+    /* Apple Clang 4.1, based on public llvm 3.1.  Atomics are not fully implemented. */
+#   define U_HAVE_STD_ATOMICS 0
+#elif __clang__ && __clang_major__==3 && __clang_minor__<=1
+    /* Clang 3.1. Atomics not fully implemented. */
+#   define U_HAVE_STD_ATOMICS 0
+#else 
+#   define U_HAVE_STD_ATOMICS 1
+#endif
+
+#else
+    /* Not C++ 11 */
+#   define U_HAVE_STD_ATOMICS 0
+#endif
+
+
+
 /*===========================================================================*/
 /** @{ Code alignment                                                        */
 /*===========================================================================*/
index 5ceca10becbb85d7a44686ce06e511a48758d5fe..8cc0ed2cbbba0fe0479dd8bd9026617c31120ec5 100644 (file)
@@ -1,6 +1,6 @@
 /*
 ***************************************************************************
-*   Copyright (C) 1999-2012 International Business Machines Corporation
+*   Copyright (C) 1999-2013 International Business Machines Corporation
 *   and others. All rights reserved.
 ***************************************************************************
 */
@@ -1793,6 +1793,7 @@ U_NAMESPACE_END
 // defined in ucln_cmn.h
 
 static icu::UStack *gLanguageBreakFactories = NULL;
+static UInitOnce    gLanguageBreakFactoriesInitOnce = U_INITONCE_INITIALIZER;
 
 /**
  * Release all static memory held by breakiterator.  
@@ -1803,6 +1804,7 @@ static UBool U_CALLCONV breakiterator_cleanup_dict(void) {
         delete gLanguageBreakFactories;
         gLanguageBreakFactories = NULL;
     }
+    gLanguageBreakFactoriesInitOnce.reset();
     return TRUE;
 }
 U_CDECL_END
@@ -1814,35 +1816,28 @@ static void U_CALLCONV _deleteFactory(void *obj) {
 U_CDECL_END
 U_NAMESPACE_BEGIN
 
-static const LanguageBreakEngine*
-getLanguageBreakEngineFromFactory(UChar32 c, int32_t breakType)
-{
-    UBool       needsInit;
-    UErrorCode  status = U_ZERO_ERROR;
-    UMTX_CHECK(NULL, (UBool)(gLanguageBreakFactories == NULL), needsInit);
-    
-    if (needsInit) {
-        UStack  *factories = new UStack(_deleteFactory, NULL, status);
-        if (factories != NULL && U_SUCCESS(status)) {
-            ICULanguageBreakFactory *builtIn = new ICULanguageBreakFactory(status);
-            factories->push(builtIn, status);
+static void U_CALLCONV initLanguageFactories() {
+    UErrorCode status = U_ZERO_ERROR;
+    U_ASSERT(gLanguageBreakFactories == NULL);
+    gLanguageBreakFactories = new UStack(_deleteFactory, NULL, status);
+    if (gLanguageBreakFactories != NULL && U_SUCCESS(status)) {
+        ICULanguageBreakFactory *builtIn = new ICULanguageBreakFactory(status);
+        gLanguageBreakFactories->push(builtIn, status);
 #ifdef U_LOCAL_SERVICE_HOOK
-            LanguageBreakFactory *extra = (LanguageBreakFactory *)uprv_svc_hook("languageBreakFactory", &status);
-            if (extra != NULL) {
-                factories->push(extra, status);
-            }
-#endif
-        }
-        umtx_lock(NULL);
-        if (gLanguageBreakFactories == NULL) {
-            gLanguageBreakFactories = factories;
-            factories = NULL;
-            ucln_common_registerCleanup(UCLN_COMMON_BREAKITERATOR_DICT, breakiterator_cleanup_dict);
+        LanguageBreakFactory *extra = (LanguageBreakFactory *)uprv_svc_hook("languageBreakFactory", &status);
+        if (extra != NULL) {
+            gLanguageBreakFactories->push(extra, status);
         }
-        umtx_unlock(NULL);
-        delete factories;
+#endif
     }
-    
+    ucln_common_registerCleanup(UCLN_COMMON_BREAKITERATOR_DICT, breakiterator_cleanup_dict);
+}
+
+
+static const LanguageBreakEngine*
+getLanguageBreakEngineFromFactory(UChar32 c, int32_t breakType)
+{
+    umtx_initOnce(gLanguageBreakFactoriesInitOnce, &initLanguageFactories);
     if (gLanguageBreakFactories == NULL) {
         return NULL;
     }
index 7073b8d931ddc9da09f99d7df30f6f9ffe255c39..5c48399645fbfc6ad9b89f785c408d0ebc0a3c2e 100644 (file)
@@ -1,7 +1,7 @@
 /*
 *******************************************************************************
 *
-*   Copyright (C) 1999-2011 International Business Machines
+*   Copyright (C) 1999-2013 International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
@@ -49,6 +49,7 @@ ubrk_swap(const UDataSwapper *ds,
 
 #include "unicode/uobject.h"
 #include "unicode/unistr.h"
+#include "umutex.h"
 #include "utrie.h"
 
 U_NAMESPACE_BEGIN
@@ -180,7 +181,7 @@ public:
     UTrie               fTrie;
 
 private:
-    int32_t             fRefCount;
+    atomic_int32_t      fRefCount;
     UDataMemory        *fUDataMem;
     UnicodeString       fRuleString;
     UBool               fDontFreeData;
index f87a572416042d6355b88ceda091b28c09790997..a2282e15d184343a876443f9a582b5c81257d6a4 100644 (file)
@@ -1,6 +1,6 @@
 /*
 **********************************************************************
-*   Copyright (C) 1997-2011, International Business Machines
+*   Copyright (C) 1997-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *
@@ -48,6 +48,9 @@
 
 #include "unicode/utypes.h"
 #include "unicode/resbund.h"
+
+#include "mutex.h"
+#include "uassert.h"
 #include "umutex.h"
 
 #include "uresimp.h"
@@ -216,6 +219,10 @@ ResourceBundle& ResourceBundle::operator=(const ResourceBundle& other)
         ures_close(fResource);
         fResource = NULL;
     }
+    if (fLocale != NULL) {
+        delete fLocale;
+        fLocale = NULL;
+    }
     UErrorCode status = U_ZERO_ERROR;
     if (other.fResource) {
         fResource = ures_copyResb(0, other.fResource, &status);
@@ -367,28 +374,17 @@ void ResourceBundle::getVersion(UVersionInfo versionInfo) const {
     ures_getVersion(fResource, versionInfo);
 }
 
-const Locale &ResourceBundle::getLocale(void) const
-{
-    UBool needInit;
-    UMTX_CHECK(NULL, (fLocale == NULL), needInit);
-    if(needInit) {
-        UErrorCode status = U_ZERO_ERROR;
-        const char *localeName = ures_getLocaleInternal(fResource, &status);
-        Locale  *tLocale = new Locale(localeName);
-        // Null pointer check
-        if (tLocale == NULL) {
-               return Locale::getDefault(); // Return default locale if one could not be created.
-        }
-        umtx_lock(NULL);
-        ResourceBundle *me = (ResourceBundle *)this; // semantically const
-        if (me->fLocale == NULL) {
-            me->fLocale = tLocale;
-            tLocale = NULL;
-        }
-        umtx_unlock(NULL);
-        delete tLocale;
+static UMutex gLocaleLock = U_MUTEX_INITIALIZER;
+const Locale &ResourceBundle::getLocale(void) const {
+    Mutex lock(&gLocaleLock);
+    if (fLocale != NULL) {
+        return *fLocale;
     }
-    return *fLocale;
+    UErrorCode status = U_ZERO_ERROR;
+    const char *localeName = ures_getLocaleInternal(fResource, &status);
+    ResourceBundle *ncThis = const_cast<ResourceBundle *>(this);
+    ncThis->fLocale = new Locale(localeName);
+    return ncThis->fLocale != NULL ? *ncThis->fLocale : Locale::getDefault();
 }
 
 const Locale ResourceBundle::getLocale(ULocDataLocaleType type, UErrorCode &status) const
@@ -396,5 +392,5 @@ const Locale ResourceBundle::getLocale(ULocDataLocaleType type, UErrorCode &stat
   return ures_getLocaleByType(fResource, type, &status);
 }
 
-//eof
 U_NAMESPACE_END
+//eof
index d9194e31e18a7db6e3afd5b3020a88191cdd5091..0fb2b3e54cbff90499b21c04661e012a4e781fb9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2009-2012, International Business Machines
+// Copyright (C) 2009-2013, International Business Machines
 // Corporation and others. All Rights Reserved.
 //
 // Copyright 2004 and onwards Google Inc.
@@ -68,15 +68,6 @@ operator==(const StringPiece& x, const StringPiece& y) {
 }
 
 
-/* Microsft Visual Studios <= 8.0 complains about redefinition of this
- * static const class variable. However, the C++ standard states that this 
- * definition is correct. Perhaps there is a bug in the Microsoft compiler. 
- * This is not an issue on any other compilers (that we know of) including 
- * Visual Studios 9.0.
- * Cygwin with MSVC 9.0 also complains here about redefinition.
- */
-#if (!defined(_MSC_VER) || (_MSC_VER >= 1500)) && !defined(CYGWINMSVC)
-const int32_t StringPiece::npos;
-#endif
+const int32_t StringPiece::npos = 0x7fffffff;
 
 U_NAMESPACE_END
index 513d796e58150f6dfd75e3b9c8018fb8a8fa3aaa..544c489ade64645618b0302e96c86934dedc698a 100644 (file)
@@ -1,6 +1,6 @@
 /*
 ******************************************************************************
-* Copyright (C) 2001-2012, International Business Machines
+* Copyright (C) 2001-2013, International Business Machines
 *                Corporation and others. All Rights Reserved.
 ******************************************************************************
 *   file name:  ucln_cmn.c
@@ -58,7 +58,6 @@ u_cleanup(void)
 
     ucln_lib_cleanup();
 
-    umtx_cleanup();
     cmemory_cleanup();       /* undo any heap functions set by u_setMemoryFunctions(). */
     gICUInitialized = FALSE;
     UTRACE_EXIT();           /* Must be before utrace_cleanup(), which turns off tracing. */
index 45c56c17ac205632ef70f844971329ae7ecbb8d4..57d15e7c141eb32335e7d973f328a85db7400398 100644 (file)
@@ -1,7 +1,7 @@
 /*
  ********************************************************************
  * COPYRIGHT:
- * Copyright (c) 1996-2012, International Business Machines Corporation and
+ * Copyright (c) 1996-2013, International Business Machines Corporation and
  * others. All Rights Reserved.
  ********************************************************************
  *
@@ -27,7 +27,9 @@
 #include "unicode/udata.h"
 #include "unicode/ucnv.h"
 #include "unicode/uloc.h"
+#include "mutex.h"
 #include "putilimp.h"
+#include "uassert.h"
 #include "utracimp.h"
 #include "ucnv_io.h"
 #include "ucnv_bld.h"
@@ -165,6 +167,7 @@ static UMutex cnvCacheMutex = U_MUTEX_INITIALIZER;  /* Mutex for synchronizing c
 
 static const char **gAvailableConverters = NULL;
 static uint16_t gAvailableConverterCount = 0;
+static UInitOnce gAvailableConvertersInitOnce = U_INITONCE_INITIALIZER;
 
 #if !U_CHARSET_IS_UTF8
 
@@ -187,15 +190,18 @@ static UBool gDefaultConverterContainsOption;
 
 static const char DATA_TYPE[] = "cnv";
 
+/* ucnv_flushAvailableConverterCache. This is only called from ucnv_cleanup().
+ *                       If it is ever to be called from elsewhere, synchronization 
+ *                       will need to be considered.
+ */
 static void
 ucnv_flushAvailableConverterCache() {
+    gAvailableConverterCount = 0;
     if (gAvailableConverters) {
-        umtx_lock(&cnvCacheMutex);
-        gAvailableConverterCount = 0;
         uprv_free((char **)gAvailableConverters);
         gAvailableConverters = NULL;
-        umtx_unlock(&cnvCacheMutex);
     }
+    gAvailableConvertersInitOnce.reset();
 }
 
 /* ucnv_cleanup - delete all storage held by the converter cache, except any  */
@@ -1110,59 +1116,46 @@ ucnv_flushCache ()
 
 /* available converters list --------------------------------------------------- */
 
-static UBool haveAvailableConverterList(UErrorCode *pErrorCode) {
-    int needInit;
-    UMTX_CHECK(&cnvCacheMutex, (gAvailableConverters == NULL), needInit);
-    if (needInit) {
-        UConverter tempConverter;
-        UEnumeration *allConvEnum = NULL;
-        uint16_t idx;
-        uint16_t localConverterCount;
-        uint16_t allConverterCount;
-        UErrorCode localStatus;
-        const char *converterName;
-        const char **localConverterList;
-
-        allConvEnum = ucnv_openAllNames(pErrorCode);
-        allConverterCount = uenum_count(allConvEnum, pErrorCode);
-        if (U_FAILURE(*pErrorCode)) {
-            return FALSE;
-        }
+static void U_CALLCONV initAvailableConvertersList(UErrorCode &errCode) {
+    U_ASSERT(gAvailableConverterCount == 0);
+    U_ASSERT(gAvailableConverters == NULL);
 
-        /* We can't have more than "*converterTable" converters to open */
-        localConverterList = (const char **) uprv_malloc(allConverterCount * sizeof(char*));
-        if (!localConverterList) {
-            *pErrorCode = U_MEMORY_ALLOCATION_ERROR;
-            return FALSE;
-        }
+    ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
+    UEnumeration *allConvEnum = ucnv_openAllNames(&errCode);
+    int32_t allConverterCount = uenum_count(allConvEnum, &errCode);
+    if (U_FAILURE(errCode)) {
+        return;
+    }
 
-        /* Open the default converter to make sure that it has first dibs in the hash table. */
-        localStatus = U_ZERO_ERROR;
-        ucnv_close(ucnv_createConverter(&tempConverter, NULL, &localStatus));
+    /* We can't have more than "*converterTable" converters to open */
+    gAvailableConverters = (const char **) uprv_malloc(allConverterCount * sizeof(char*));
+    if (!gAvailableConverters) {
+        errCode = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
 
-        localConverterCount = 0;
+    /* Open the default converter to make sure that it has first dibs in the hash table. */
+    UErrorCode localStatus = U_ZERO_ERROR;
+    UConverter tempConverter;
+    ucnv_close(ucnv_createConverter(&tempConverter, NULL, &localStatus));
 
-        for (idx = 0; idx < allConverterCount; idx++) {
-            localStatus = U_ZERO_ERROR;
-            converterName = uenum_next(allConvEnum, NULL, &localStatus);
-            if (ucnv_canCreateConverter(converterName, &localStatus)) {
-                localConverterList[localConverterCount++] = converterName;
-            }
-        }
-        uenum_close(allConvEnum);
+    gAvailableConverterCount = 0;
 
-        umtx_lock(&cnvCacheMutex);
-        if (gAvailableConverters == NULL) {
-            gAvailableConverterCount = localConverterCount;
-            gAvailableConverters = localConverterList;
-            ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
-        }
-        else {
-            uprv_free((char **)localConverterList);
+    for (int32_t idx = 0; idx < allConverterCount; idx++) {
+        localStatus = U_ZERO_ERROR;
+        const char *converterName = uenum_next(allConvEnum, NULL, &localStatus);
+        if (ucnv_canCreateConverter(converterName, &localStatus)) {
+            gAvailableConverters[gAvailableConverterCount++] = converterName;
         }
-        umtx_unlock(&cnvCacheMutex);
     }
-    return TRUE;
+
+    uenum_close(allConvEnum);
+}
+
+
+static UBool haveAvailableConverterList(UErrorCode *pErrorCode) {
+    umtx_initOnce(gAvailableConvertersInitOnce, &initAvailableConvertersList, *pErrorCode);
+    return U_SUCCESS(*pErrorCode);
 }
 
 U_CFUNC uint16_t
@@ -1228,6 +1221,9 @@ internalSetName(const char *name, UErrorCode *status) {
 
     /* gDefaultConverterName MUST be the last global var set by this function.  */
     /*    It is the variable checked in ucnv_getDefaultName() to see if initialization is required. */
+    //    But there is nothing here preventing that from being reordered, either by the compiler
+    //             or hardware. I'm adding the mutex to ucnv_getDefaultName for now. UMTX_CHECK is not enough.
+    //             -- Andy
     gDefaultConverterName = gDefaultConverterNameBuffer;
 
     ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
@@ -1253,10 +1249,13 @@ ucnv_getDefaultName() {
     const char *name;
 
     /*
-    Multiple calls to ucnv_getDefaultName must be thread safe,
+    Concurrent calls to ucnv_getDefaultName must be thread safe,
     but ucnv_setDefaultName is not thread safe.
     */
-    UMTX_CHECK(&cnvCacheMutex, gDefaultConverterName, name);
+    {
+        icu::Mutex lock(&cnvCacheMutex);
+        name = gDefaultConverterName;
+    }
     if(name==NULL) {
         UErrorCode errorCode = U_ZERO_ERROR;
         UConverter *cnv = NULL;
index 12d2b63f0d8cbbf551e7928305425335cfabccfa..091a1b7c6c3ef6f41da3eb18674e635ff23d65c2 100644 (file)
@@ -1,7 +1,7 @@
 /*
 ******************************************************************************
 *
-*   Copyright (C) 1999-2012, International Business Machines
+*   Copyright (C) 1999-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
@@ -36,6 +36,7 @@
 
 #include "umutex.h"
 #include "uarrsort.h"
+#include "uassert.h"
 #include "udataswp.h"
 #include "cstring.h"
 #include "cmemory.h"
@@ -172,6 +173,7 @@ static const char DATA_NAME[] = "cnvalias";
 static const char DATA_TYPE[] = "icu";
 
 static UDataMemory *gAliasData=NULL;
+static UInitOnce    gAliasDataInitOnce = U_INITONCE_INITIALIZER;
 
 enum {
     tocLengthIndex=0,
@@ -218,113 +220,97 @@ static UBool U_CALLCONV ucnv_io_cleanup(void)
         udata_close(gAliasData);
         gAliasData = NULL;
     }
+    gAliasDataInitOnce.reset();
 
     uprv_memset(&gMainTable, 0, sizeof(gMainTable));
 
     return TRUE;                   /* Everything was cleaned up */
 }
 
-static UBool
-haveAliasData(UErrorCode *pErrorCode) {
-    int needInit;
-
-    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
-        return FALSE;
-    }
-
-    UMTX_CHECK(NULL, (gAliasData==NULL), needInit);
+static void U_CALLCONV initAliasData(UErrorCode &errCode) {
+    UDataMemory *data;
+    const uint16_t *table;
+    const uint32_t *sectionSizes;
+    uint32_t tableStart;
+    uint32_t currOffset;
 
-    /* load converter alias data from file if necessary */
-    if (needInit) {
-        UDataMemory *data;
-        const uint16_t *table;
-        const uint32_t *sectionSizes;
-        uint32_t tableStart;
-        uint32_t currOffset;
+    ucln_common_registerCleanup(UCLN_COMMON_UCNV_IO, ucnv_io_cleanup);
 
-        data = udata_openChoice(NULL, DATA_TYPE, DATA_NAME, isAcceptable, NULL, pErrorCode);
-        if(U_FAILURE(*pErrorCode)) {
-            return FALSE;
-        }
-
-        sectionSizes = (const uint32_t *)udata_getMemory(data);
-        table = (const uint16_t *)sectionSizes;
-
-        tableStart      = sectionSizes[0];
-        if (tableStart < minTocLength) {
-            *pErrorCode = U_INVALID_FORMAT_ERROR;
-            udata_close(data);
-            return FALSE;
-        }
-
-        umtx_lock(NULL);
-        if(gAliasData==NULL) {
-            gMainTable.converterListSize      = sectionSizes[1];
-            gMainTable.tagListSize            = sectionSizes[2];
-            gMainTable.aliasListSize          = sectionSizes[3];
-            gMainTable.untaggedConvArraySize  = sectionSizes[4];
-            gMainTable.taggedAliasArraySize   = sectionSizes[5];
-            gMainTable.taggedAliasListsSize   = sectionSizes[6];
-            gMainTable.optionTableSize        = sectionSizes[7];
-            gMainTable.stringTableSize        = sectionSizes[8];
-
-            if (tableStart > 8) {
-                gMainTable.normalizedStringTableSize = sectionSizes[9];
-            }
+    U_ASSERT(gAliasData == NULL);
+    data = udata_openChoice(NULL, DATA_TYPE, DATA_NAME, isAcceptable, NULL, &errCode);
+    if(U_FAILURE(errCode)) {
+        return;
+    }
 
-            currOffset = tableStart * (sizeof(uint32_t)/sizeof(uint16_t)) + (sizeof(uint32_t)/sizeof(uint16_t));
-            gMainTable.converterList = table + currOffset;
+    sectionSizes = (const uint32_t *)udata_getMemory(data);
+    table = (const uint16_t *)sectionSizes;
 
-            currOffset += gMainTable.converterListSize;
-            gMainTable.tagList = table + currOffset;
+    tableStart      = sectionSizes[0];
+    if (tableStart < minTocLength) {
+        errCode = U_INVALID_FORMAT_ERROR;
+        udata_close(data);
+        return;
+    }
+    gAliasData = data;
+
+    gMainTable.converterListSize      = sectionSizes[1];
+    gMainTable.tagListSize            = sectionSizes[2];
+    gMainTable.aliasListSize          = sectionSizes[3];
+    gMainTable.untaggedConvArraySize  = sectionSizes[4];
+    gMainTable.taggedAliasArraySize   = sectionSizes[5];
+    gMainTable.taggedAliasListsSize   = sectionSizes[6];
+    gMainTable.optionTableSize        = sectionSizes[7];
+    gMainTable.stringTableSize        = sectionSizes[8];
+
+    if (tableStart > 8) {
+        gMainTable.normalizedStringTableSize = sectionSizes[9];
+    }
 
-            currOffset += gMainTable.tagListSize;
-            gMainTable.aliasList = table + currOffset;
+    currOffset = tableStart * (sizeof(uint32_t)/sizeof(uint16_t)) + (sizeof(uint32_t)/sizeof(uint16_t));
+    gMainTable.converterList = table + currOffset;
 
-            currOffset += gMainTable.aliasListSize;
-            gMainTable.untaggedConvArray = table + currOffset;
+    currOffset += gMainTable.converterListSize;
+    gMainTable.tagList = table + currOffset;
 
-            currOffset += gMainTable.untaggedConvArraySize;
-            gMainTable.taggedAliasArray = table + currOffset;
+    currOffset += gMainTable.tagListSize;
+    gMainTable.aliasList = table + currOffset;
 
-            /* aliasLists is a 1's based array, but it has a padding character */
-            currOffset += gMainTable.taggedAliasArraySize;
-            gMainTable.taggedAliasLists = table + currOffset;
+    currOffset += gMainTable.aliasListSize;
+    gMainTable.untaggedConvArray = table + currOffset;
 
-            currOffset += gMainTable.taggedAliasListsSize;
-            if (gMainTable.optionTableSize > 0
-                && ((const UConverterAliasOptions *)(table + currOffset))->stringNormalizationType < UCNV_IO_NORM_TYPE_COUNT)
-            {
-                /* Faster table */
-                gMainTable.optionTable = (const UConverterAliasOptions *)(table + currOffset);
-            }
-            else {
-                /* Smaller table, or I can't handle this normalization mode!
-                Use the original slower table lookup. */
-                gMainTable.optionTable = &defaultTableOptions;
-            }
+    currOffset += gMainTable.untaggedConvArraySize;
+    gMainTable.taggedAliasArray = table + currOffset;
 
-            currOffset += gMainTable.optionTableSize;
-            gMainTable.stringTable = table + currOffset;
+    /* aliasLists is a 1's based array, but it has a padding character */
+    currOffset += gMainTable.taggedAliasArraySize;
+    gMainTable.taggedAliasLists = table + currOffset;
 
-            currOffset += gMainTable.stringTableSize;
-            gMainTable.normalizedStringTable = ((gMainTable.optionTable->stringNormalizationType == UCNV_IO_UNNORMALIZED)
-                ? gMainTable.stringTable : (table + currOffset));
+    currOffset += gMainTable.taggedAliasListsSize;
+    if (gMainTable.optionTableSize > 0
+        && ((const UConverterAliasOptions *)(table + currOffset))->stringNormalizationType < UCNV_IO_NORM_TYPE_COUNT)
+    {
+        /* Faster table */
+        gMainTable.optionTable = (const UConverterAliasOptions *)(table + currOffset);
+    }
+    else {
+        /* Smaller table, or I can't handle this normalization mode!
+        Use the original slower table lookup. */
+        gMainTable.optionTable = &defaultTableOptions;
+    }
 
-            ucln_common_registerCleanup(UCLN_COMMON_UCNV_IO, ucnv_io_cleanup);
+    currOffset += gMainTable.optionTableSize;
+    gMainTable.stringTable = table + currOffset;
 
-            gAliasData = data;
-            data=NULL;
-        }
-        umtx_unlock(NULL);
+    currOffset += gMainTable.stringTableSize;
+    gMainTable.normalizedStringTable = ((gMainTable.optionTable->stringNormalizationType == UCNV_IO_UNNORMALIZED)
+        ? gMainTable.stringTable : (table + currOffset));
+}
 
-        /* if a different thread set it first, then close the extra data */
-        if(data!=NULL) {
-            udata_close(data); /* NULL if it was set correctly */
-        }
-    }
 
-    return TRUE;
+static UBool
+haveAliasData(UErrorCode *pErrorCode) {
+    umtx_initOnce(gAliasDataInitOnce, &initAliasData, *pErrorCode);
+    return U_SUCCESS(*pErrorCode);
 }
 
 static inline UBool
@@ -351,7 +337,7 @@ static uint32_t getTagNumber(const char *tagname) {
 
 /* character types relevant for ucnv_compareNames() */
 enum {
-    IGNORE,
+    UIGNORE,
     ZERO,
     NONZERO,
     MINLETTER /* any values from here on are lowercase letter mappings */
@@ -369,7 +355,7 @@ static const uint8_t asciiTypes[128] = {
     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0, 0, 0, 0, 0
 };
 
-#define GET_ASCII_TYPE(c) ((int8_t)(c) >= 0 ? asciiTypes[(uint8_t)c] : (uint8_t)IGNORE)
+#define GET_ASCII_TYPE(c) ((int8_t)(c) >= 0 ? asciiTypes[(uint8_t)c] : (uint8_t)UIGNORE)
 
 /* character types for EBCDIC 80..FF */
 static const uint8_t ebcdicTypes[128] = {
@@ -383,7 +369,7 @@ static const uint8_t ebcdicTypes[128] = {
     ZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, 0, 0, 0, 0, 0, 0
 };
 
-#define GET_EBCDIC_TYPE(c) ((int8_t)(c) < 0 ? ebcdicTypes[(c)&0x7f] : (uint8_t)IGNORE)
+#define GET_EBCDIC_TYPE(c) ((int8_t)(c) < 0 ? ebcdicTypes[(c)&0x7f] : (uint8_t)UIGNORE)
 
 #if U_CHARSET_FAMILY==U_ASCII_FAMILY
 #   define GET_CHAR_TYPE(c) GET_ASCII_TYPE(c)
@@ -404,7 +390,7 @@ ucnv_io_stripASCIIForCompare(char *dst, const char *name) {
     while ((c1 = *name++) != 0) {
         type = GET_ASCII_TYPE(c1);
         switch (type) {
-        case IGNORE:
+        case UIGNORE:
             afterDigit = FALSE;
             continue; /* ignore all but letters and digits */
         case ZERO:
@@ -439,7 +425,7 @@ ucnv_io_stripEBCDICForCompare(char *dst, const char *name) {
     while ((c1 = *name++) != 0) {
         type = GET_EBCDIC_TYPE(c1);
         switch (type) {
-        case IGNORE:
+        case UIGNORE:
             afterDigit = FALSE;
             continue; /* ignore all but letters and digits */
         case ZERO:
@@ -496,7 +482,7 @@ ucnv_compareNames(const char *name1, const char *name2) {
         while ((c1 = *name1++) != 0) {
             type = GET_CHAR_TYPE(c1);
             switch (type) {
-            case IGNORE:
+            case UIGNORE:
                 afterDigit1 = FALSE;
                 continue; /* ignore all but letters and digits */
             case ZERO:
@@ -520,7 +506,7 @@ ucnv_compareNames(const char *name1, const char *name2) {
         while ((c2 = *name2++) != 0) {
             type = GET_CHAR_TYPE(c2);
             switch (type) {
-            case IGNORE:
+            case UIGNORE:
                 afterDigit2 = FALSE;
                 continue; /* ignore all but letters and digits */
             case ZERO:
index 0837893eeb0fa8f71b1df87c33c77b3f3bb8e936..3c70721613440c7cd1aa572c332ab3beb0c8c1b3 100644 (file)
@@ -30,6 +30,7 @@ might have to #include some other header
 #include "cmemory.h"
 #include "cstring.h"
 #include "putilimp.h"
+#include "uassert.h"
 #include "ucln_cmn.h"
 #include "ucmndata.h"
 #include "udatamem.h"
@@ -106,6 +107,7 @@ static UDataMemory *gCommonICUDataArray[10] = { NULL };
 static UBool gHaveTriedToLoadCommonData = FALSE;  /* See extendICUData(). */
 
 static UHashtable  *gCommonDataCache = NULL;  /* Global hash table of opened ICU data files.  */
+static UInitOnce    gCommonDataCacheInitOnce = U_INITONCE_INITIALIZER;
 
 static UDataFileAccess  gDataFileAccess = UDATA_DEFAULT_ACCESS;
 
@@ -118,6 +120,7 @@ udata_cleanup(void)
         uhash_close(gCommonDataCache);  /*   Table owns the contents, and will delete them. */
         gCommonDataCache = NULL;        /*   Cleanup is not thread safe.                */
     }
+    gCommonDataCacheInitOnce.reset();
 
     for (i = 0; i < LENGTHOF(gCommonICUDataArray) && gCommonICUDataArray[i] != NULL; ++i) {
         udata_close(gCommonICUDataArray[i]);
@@ -262,42 +265,26 @@ static void U_CALLCONV DataCacheElement_deleter(void *pDCEl) {
     uprv_free(pDCEl);                  /* delete 'this'          */
 }
 
- /*   udata_getCacheHashTable()
- *     Get the hash table used to store the data cache entries.
- *     Lazy create it if it doesn't yet exist.
- */
-static UHashtable *udata_getHashTable() {
-    UErrorCode   err = U_ZERO_ERROR;
-    UBool        cacheIsInitialized;
-    UHashtable  *tHT = NULL;
-
-    UMTX_CHECK(NULL, (gCommonDataCache != NULL), cacheIsInitialized);
-
-    if (cacheIsInitialized) {
-        return gCommonDataCache;
-    }
-
-    tHT = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &err);
-    /* Check for null pointer. */
-    if (tHT == NULL) {
-       return NULL; /* TODO:  Handle this error better. */
+static void udata_initHashTable() {
+    UErrorCode err = U_ZERO_ERROR;
+    U_ASSERT(gCommonDataCache == NULL);
+    gCommonDataCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &err);
+    if (U_FAILURE(err)) {
+        // TODO: handle errors better.
+        gCommonDataCache = NULL;
     }
-    uhash_setValueDeleter(tHT, DataCacheElement_deleter);
-
-    umtx_lock(NULL);
-    if (gCommonDataCache == NULL) {
-        gCommonDataCache = tHT;
-        tHT = NULL;
+    if (gCommonDataCache != NULL) {
+        uhash_setValueDeleter(gCommonDataCache, DataCacheElement_deleter);
         ucln_common_registerCleanup(UCLN_COMMON_UDATA, udata_cleanup);
     }
-    umtx_unlock(NULL);
-    if (tHT != NULL) {
-        uhash_close(tHT);
-    }
+}
 
-    if (U_FAILURE(err)) {
-        return NULL;      /* TODO:  handle this error better.  */
-    }
+ /*   udata_getCacheHashTable()
+  *     Get the hash table used to store the data cache entries.
+  *     Lazy create it if it doesn't yet exist.
+  */
+static UHashtable *udata_getHashTable() {
+    umtx_initOnce(gCommonDataCacheInitOnce, &udata_initHashTable);
     return gCommonDataCache;
 }
 
index a7299a5cfd1603721fb58d7b3f5608d3d03131da..b217e787b279a39a9ee4ee9db90570ddb8a872e8 100644 (file)
@@ -1,7 +1,7 @@
 /*
 ******************************************************************************
 *
-*   Copyright (C) 1997-2012, International Business Machines
+*   Copyright (C) 1997-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
 ******************************************************************************
 */
 
+#include "umutex.h"
+
 #include "unicode/utypes.h"
 #include "uassert.h"
+#include "cmemory.h"
 #include "ucln_cmn.h"
 
+// The ICU global mutex. Used when ICU implementation code passes NULL for the mutex pointer.
+static UMutex   globalMutex = U_MUTEX_INITIALIZER;
+
 /*
  * ICU Mutex wrappers.  Wrap operating system mutexes, giving the rest of ICU a
  * platform independent set of mutex operations.  For internal ICU use only.
  */
 
 #if U_PLATFORM_HAS_WIN32_API
-    /* Prefer native Windows APIs even if POSIX is implemented (i.e., on Cygwin). */
-#   undef POSIX
-#elif U_PLATFORM_IMPLEMENTS_POSIX
-#   define POSIX
-#else
-#   undef POSIX
-#endif
-
-#if defined(POSIX)
-# include <pthread.h> /* must be first, so that we get the multithread versions of things. */
-#endif /* POSIX */
-
-#if U_PLATFORM_HAS_WIN32_API
-# define WIN32_LEAN_AND_MEAN
-# define VC_EXTRALEAN
-# define NOUSER
-# define NOSERVICE
-# define NOIME
-# define NOMCX
-# include <windows.h>
-#endif
-
-#include "umutex.h"
-#include "cmemory.h"
 
-#if U_PLATFORM_HAS_WIN32_API
-#define SYNC_COMPARE_AND_SWAP(dest, oldval, newval) \
-            InterlockedCompareExchangePointer(dest, newval, oldval)
-
-#elif defined(POSIX)
-#if (U_HAVE_GCC_ATOMICS == 1)
-#define SYNC_COMPARE_AND_SWAP(dest, oldval, newval) \
-            __sync_val_compare_and_swap(dest, oldval, newval)
-#else
-#define SYNC_COMPARE_AND_SWAP(dest, oldval, newval) \
-            mutexed_compare_and_swap(dest, newval, oldval)
-#endif
+//-------------------------------------------------------------------------------------------
+//
+//    Windows Specific Definitions
+//
+//        Note: Cygwin (and possibly others) have both WIN32 and POSIX.
+//              Prefer Win32 in these cases.  (Win32 comes ahead in the #if chain)
+//
+//-------------------------------------------------------------------------------------------
 
-#else   
-// Unknown platform.  Note that user can still set mutex functions at run time.
-#define SYNC_COMPARE_AND_SWAP(dest, oldval, newval) \
-            mutexed_compare_and_swap(dest, newval, oldval)
+#if defined U_NO_PLATFORM_ATOMICS
+#error ICU on Win32 requires support for low level atomic operations.
+// Visual Studio, gcc, clang are OK. Shouldn't get here.
 #endif
 
-static void *mutexed_compare_and_swap(void **dest, void *newval, void *oldval);
 
-// The ICU global mutex. Used when ICU implementation code passes NULL for the mutex pointer.
-static UMutex   globalMutex = U_MUTEX_INITIALIZER;
-
-// Implementation mutex. Used for compare & swap when no intrinsic is available, and
-// for safe initialization of user defined mutexes.
-static UMutex   implMutex = U_MUTEX_INITIALIZER;      
-
-// List of all user mutexes that have been initialized.
-// Used to allow us to destroy them when cleaning up ICU.
-// Normal platform mutexes are not kept track of in this way - they survive until the process is shut down.
-// Normal platfrom mutexes don't allocate storage, so not cleaning them up won't trigger memory leak complaints.
+// This function is called when a test of a UInitOnce::fState reveals that
+//   initialization has not completed, that we either need to call the
+//   function on this thread, or wait for some other thread to complete.
 //
-// Note: putting this list in allocated memory would be awkward to arrange, because memory allocations
-//       are used as a flag to indicate that ICU has been initialized, and setting other ICU 
-//       override functions will no longer work.
+// The actual call to the init function is made inline by template code
+//   that knows the C++ types involved. This function returns TRUE if
+//   the caller needs to call the Init function.
 //
-static const int MUTEX_LIST_LIMIT = 100;
-static UMutex *gMutexList[MUTEX_LIST_LIMIT];
-static int gMutexListSize = 0;
-
-
-/*
- *  User mutex implementation functions.  If non-null, call back to these rather than
- *  directly using the system (Posix or Windows) APIs.  See u_setMutexFunctions().
- *    (declarations are in uclean.h)
- */
-static UMtxInitFn    *pMutexInitFn    = NULL;
-static UMtxFn        *pMutexDestroyFn = NULL;
-static UMtxFn        *pMutexLockFn    = NULL;
-static UMtxFn        *pMutexUnlockFn  = NULL;
-static const void    *gMutexContext   = NULL;
 
-
-// Clean up (undo) the effects of u_setMutexFunctions().
-//
-static void usrMutexCleanup() {
-    if (pMutexDestroyFn != NULL) {
-        for (int i = 0; i < gMutexListSize; i++) {
-            UMutex *m = gMutexList[i];
-            U_ASSERT(m->fInitialized);
-            (*pMutexDestroyFn)(gMutexContext, &m->fUserMutex);
-            m->fInitialized = FALSE;
+U_CAPI UBool U_EXPORT2 umtx_initImplPreInit(UInitOnce &uio) {
+    for (;;) {
+        int32_t previousState = InterlockedCompareExchange( 
+            &uio.fState,  //  Destination
+            1,            //  Exchange Value
+            0);           //  Compare value
+
+        if (previousState == 0) {
+            return true;   // Caller will next call the init function.
+                           // Current state == 1.
+        } else if (previousState == 2) {
+            // Another thread already completed the initialization.
+            //   We can simply return FALSE, indicating no
+            //   further action is needed by the caller.
+            return FALSE;
+        } else {
+            // Another thread is currently running the initialization.
+            // Wait until it completes.
+            do {
+                Sleep(1);
+                previousState = umtx_loadAcquire(uio.fState);
+            } while (previousState == 1);
         }
-        (*pMutexDestroyFn)(gMutexContext, &globalMutex.fUserMutex);
-        (*pMutexDestroyFn)(gMutexContext, &implMutex.fUserMutex);
     }
-    gMutexListSize  = 0;
-    pMutexInitFn    = NULL;
-    pMutexDestroyFn = NULL;
-    pMutexLockFn    = NULL;
-    pMutexUnlockFn  = NULL;
-    gMutexContext   = NULL;
 }
 
-
-/*
- * User mutex lock.
- *
- * User mutexes need to be initialized before they can be used. We use the impl mutex
- * to synchronize the initialization check. This could be sped up on platforms that
- * support alternate ways to safely check the initialization flag.
- *
- */
-static void usrMutexLock(UMutex *mutex) {
-    UErrorCode status = U_ZERO_ERROR;
-    if (!(mutex == &implMutex || mutex == &globalMutex)) {
-        umtx_lock(&implMutex);
-        if (!mutex->fInitialized) {
-            (*pMutexInitFn)(gMutexContext, &mutex->fUserMutex, &status);
-            U_ASSERT(U_SUCCESS(status));
-            mutex->fInitialized = TRUE;
-            U_ASSERT(gMutexListSize < MUTEX_LIST_LIMIT);
-            if (gMutexListSize < MUTEX_LIST_LIMIT) {
-                gMutexList[gMutexListSize] = mutex;
-                ++gMutexListSize;
-            }
-        }
-        umtx_unlock(&implMutex);
-    }
-    (*pMutexLockFn)(gMutexContext, &mutex->fUserMutex);
+// This function is called by the thread that ran an initialization function,
+// just after completing the function.
+//
+//   success: True:  the inialization succeeded. No further calls to the init
+//                   function will be made.
+//            False: the initializtion failed. The next call to umtx_initOnce()
+//                   will retry the initialization.
+
+U_CAPI void U_EXPORT2 umtx_initImplPostInit(UInitOnce &uio, UBool success) {
+    int32_t nextState = success? 2: 0;
+    umtx_storeRelease(uio.fState, nextState);
 }
-        
-
 
-#if defined(POSIX)
 
-//
-// POSIX implementation of UMutex.
-//
-// Each UMutex has a corresponding pthread_mutex_t.
-// All are statically initialized and ready for use.
-// There is no runtime mutex initialization code needed.
+static void winMutexInit(CRITICAL_SECTION *cs) {
+    InitializeCriticalSection(cs);
+    return;
+}
 
 U_CAPI void  U_EXPORT2
 umtx_lock(UMutex *mutex) {
     if (mutex == NULL) {
         mutex = &globalMutex;
     }
-    if (pMutexLockFn) {
-        usrMutexLock(mutex);
-    } else {
-        #if U_DEBUG
-            // #if to avoid unused variable warnings in non-debug builds.
-            int sysErr = pthread_mutex_lock(&mutex->fMutex);
-            U_ASSERT(sysErr == 0);
-        #else
-            pthread_mutex_lock(&mutex->fMutex);
-        #endif
-    }
+    CRITICAL_SECTION *cs = &mutex->fCS;
+    umtx_initOnce(mutex->fInitOnce, winMutexInit, cs);
+    EnterCriticalSection(cs);
 }
 
-
 U_CAPI void  U_EXPORT2
 umtx_unlock(UMutex* mutex)
 {
     if (mutex == NULL) {
         mutex = &globalMutex;
     }
-    if (pMutexUnlockFn) {
-        (*pMutexUnlockFn)(gMutexContext, &mutex->fUserMutex);
-    } else {
-        #if U_DEBUG
-            // #if to avoid unused variable warnings in non-debug builds.
-            int sysErr = pthread_mutex_unlock(&mutex->fMutex);
-            U_ASSERT(sysErr == 0);
-        #else
-            pthread_mutex_unlock(&mutex->fMutex);
-        #endif
-    }
+    LeaveCriticalSection(&mutex->fCS);
 }
 
-#elif U_PLATFORM_HAS_WIN32_API
-//
-// Windows implementation of UMutex.
+#elif U_PLATFORM_IMPLEMENTS_POSIX
+
+//-------------------------------------------------------------------------------------------
 //
-// Each UMutex has a corresponding Windows CRITICAL_SECTION.
-// CRITICAL_SECTIONS must be initialized before use. This is done
-//   with a InitOnceExcuteOnce operation.
+//  POSIX specific definitions
 //
-// InitOnceExecuteOnce was introduced with Windows Vista. For now ICU
-// must support Windows XP, so we roll our own. ICU will switch to the
-// native Windows InitOnceExecuteOnce when possible.
-
-typedef UBool (*U_PINIT_ONCE_FN) (
-  U_INIT_ONCE     *initOnce,
-  void            *parameter,
-  void            **context
-);
-
-UBool u_InitOnceExecuteOnce(
-  U_INIT_ONCE     *initOnce,
-  U_PINIT_ONCE_FN initFn,
-  void            *parameter,
-  void            **context) {
-      for (;;) {
-          long previousState = InterlockedCompareExchange( 
-              &initOnce->fState,  //  Destination,
-              1,                  //  Exchange Value
-              0);                 //  Compare value
-          if (previousState == 2) {
-              // Initialization was already completed.
-              if (context != NULL) {
-                  *context = initOnce->fContext;
-              }
-              return TRUE;
-          }
-          if (previousState == 1) {
-              // Initialization is in progress in some other thread.
-              // Loop until it completes.
-              Sleep(1);
-              continue;
-          }
-           
-          // Initialization needed. Execute the callback function to do it.
-          U_ASSERT(previousState == 0);
-          U_ASSERT(initOnce->fState == 1);
-          UBool success = (*initFn)(initOnce, parameter, &initOnce->fContext);
-          U_ASSERT(success); // ICU is not supporting the failure case.
-
-          // Assign the state indicating that initialization has completed.
-          // Using InterlockedCompareExchange to do it ensures that all
-          // threads will have a consistent view of memory.
-          previousState = InterlockedCompareExchange(&initOnce->fState, 2, 1);
-          U_ASSERT(previousState == 1);
-          // Next loop iteration will see the initialization and return.
-      }
-};
-
-static UBool winMutexInit(U_INIT_ONCE *initOnce, void *param, void **context) {
-    UMutex *mutex = static_cast<UMutex *>(param);
-    U_ASSERT(sizeof(CRITICAL_SECTION) <= sizeof(mutex->fCS));
-    InitializeCriticalSection((CRITICAL_SECTION *)mutex->fCS);
-    return TRUE;
-}
+//-------------------------------------------------------------------------------------------
+
+# include <pthread.h> 
+
+// Each UMutex consists of a pthread_mutex_t.
+// All are statically initialized and ready for use.
+// There is no runtime mutex initialization code needed.
 
-/*
- *   umtx_lock
- */
 U_CAPI void  U_EXPORT2
 umtx_lock(UMutex *mutex) {
     if (mutex == NULL) {
         mutex = &globalMutex;
     }
-    if (pMutexLockFn) {
-        usrMutexLock(mutex);
-    } else {
-        u_InitOnceExecuteOnce(&mutex->fInitOnce, winMutexInit, mutex, NULL);
-        EnterCriticalSection((CRITICAL_SECTION *)mutex->fCS);
-    }
+    int sysErr = pthread_mutex_lock(&mutex->fMutex);
+    (void)sysErr;   // Suppress unused variable warnings.
+    U_ASSERT(sysErr == 0);
 }
 
+
 U_CAPI void  U_EXPORT2
 umtx_unlock(UMutex* mutex)
 {
     if (mutex == NULL) {
         mutex = &globalMutex;
     }
-    if (pMutexUnlockFn) {
-        (*pMutexUnlockFn)(gMutexContext, &mutex->fUserMutex);
-    } else {
-        LeaveCriticalSection((CRITICAL_SECTION *)mutex->fCS);
-    }
+    int sysErr = pthread_mutex_unlock(&mutex->fMutex);
+    (void)sysErr;   // Suppress unused variable warnings.
+    U_ASSERT(sysErr == 0);
 }
 
-#endif  // Windows Implementation
-
-
-U_CAPI void U_EXPORT2 
-u_setMutexFunctions(const void *context, UMtxInitFn *i, UMtxFn *d, UMtxFn *l, UMtxFn *u,
-                    UErrorCode *status) {
-    if (U_FAILURE(*status)) {
-        return;
-    }
+static pthread_mutex_t initMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t initCondition = PTHREAD_COND_INITIALIZER;
 
-    /* Can not set a mutex function to a NULL value  */
-    if (i==NULL || d==NULL || l==NULL || u==NULL) {
-        *status = U_ILLEGAL_ARGUMENT_ERROR;
-        return;
-    }
 
-    /* If ICU is not in an initial state, disallow this operation. */
-    if (cmemory_inUse()) {
-        *status = U_INVALID_STATE_ERROR;
-        return;
+// This function is called when a test of a UInitOnce::fState reveals that
+//   initialization has not completed, that we either need to call the
+//   function on this thread, or wait for some other thread to complete.
+//
+// The actual call to the init function is made inline by template code
+//   that knows the C++ types involved. This function returns TRUE if
+//   the caller needs to call the Init function.
+//
+UBool umtx_initImplPreInit(UInitOnce &uio) {
+    pthread_mutex_lock(&initMutex);
+    int32_t state = uio.fState;
+    if (state == 0) {
+        umtx_storeRelease(uio.fState, 1);
+        pthread_mutex_unlock(&initMutex);
+        return true;   // Caller will next call the init function.
+    } else if (state == 2) {
+        // Another thread already completed the initialization, in
+        //   a race with this thread. We can simply return FALSE, indicating no
+        //   further action is needed by the caller.
+        pthread_mutex_unlock(&initMutex);
+        return FALSE;
+    } else {
+        // Another thread is currently running the initialization.
+        // Wait until it completes.
+        U_ASSERT(state == 1);
+        while (uio.fState == 1) {
+            pthread_cond_wait(&initCondition, &initMutex);
+        }
+        UBool returnVal = uio.fState == 0;
+        if (returnVal) {
+            // Initialization that was running in another thread failed.
+            // We will retry it in this thread.
+            // (This is only used by SimpleSingleton)
+            umtx_storeRelease(uio.fState, 1);
+        }
+        pthread_mutex_unlock(&initMutex);
+        return returnVal;
     }
-
-    // Clean up any previously set user mutex functions.
-    // It's possible to call u_setMutexFunctions() more than once without without explicitly cleaning up,
-    // and the last call should take. Kind of a corner case, but it worked once, there is a test for
-    // it, so we keep it working. The global and impl mutexes will have been created by the
-    // previous u_setMutexFunctions(), and now need to be destroyed.
-
-    usrMutexCleanup();
-    
-    /* Swap in the mutex function pointers.  */
-    pMutexInitFn    = i;
-    pMutexDestroyFn = d;
-    pMutexLockFn    = l;
-    pMutexUnlockFn  = u;
-    gMutexContext   = context;
-    gMutexListSize  = 0;
-
-    /* Initialize the global and impl mutexes. Safe to do at this point because
-     * u_setMutexFunctions must be done in a single-threaded envioronment. Not thread safe.
-     */
-    (*pMutexInitFn)(gMutexContext, &globalMutex.fUserMutex, status);
-    globalMutex.fInitialized = TRUE;
-    (*pMutexInitFn)(gMutexContext, &implMutex.fUserMutex, status);
-    implMutex.fInitialized = TRUE;
 }
 
+// This function is called by the thread that ran an initialization function,
+// just after completing the function.
+//   Some threads may be waiting on the condition, requiring the broadcast wakeup.
+//   Some threads may be racing to test the fState variable outside of the mutex, 
+//   requiring the use of store/release when changing its value.
+//
+//   success: True:  the inialization succeeded. No further calls to the init
+//                   function will be made.
+//            False: the initializtion failed. The next call to umtx_initOnce()
+//                   will retry the initialization.
+
+void umtx_initImplPostInit(UInitOnce &uio, UBool success) {
+    int32_t nextState = success? 2: 0;
+    pthread_mutex_lock(&initMutex);
+    umtx_storeRelease(uio.fState, nextState);
+    pthread_cond_broadcast(&initCondition);
+    pthread_mutex_unlock(&initMutex);
+}
 
 
-/*   synchronized compare and swap function, for use when OS or compiler built-in
- *   equivalents aren't available.
- */
-static void *mutexed_compare_and_swap(void **dest, void *newval, void *oldval) {
-    umtx_lock(&implMutex);
-    void *temp = *dest;
-    if (temp == oldval) {
-        *dest = newval;
-    }
-    umtx_unlock(&implMutex);
-    
-    return temp;
+void umtx_initOnceReset(UInitOnce &uio) {
+    // Not a thread safe function, we can use an ordinary assignment.
+    uio.fState = 0;
 }
+        
+// End of POSIX specific umutex implementation.
 
+#else  // Platform #define chain.
 
+#error Unknown Platform
 
-/*-----------------------------------------------------------------
- *
- *  Atomic Increment and Decrement
- *     umtx_atomic_inc
- *     umtx_atomic_dec
- *
- *----------------------------------------------------------------*/
+#endif  // Platform #define chain.
 
-/* Pointers to user-supplied inc/dec functions.  Null if no funcs have been set.  */
-static UMtxAtomicFn  *pIncFn = NULL;
-static UMtxAtomicFn  *pDecFn = NULL;
-static const void *gIncDecContext  = NULL;
 
-#if defined (POSIX) && (U_HAVE_GCC_ATOMICS == 0)
+//-------------------------------------------------------------------------------
+//
+//   Atomic Operations, out-of-line versions.
+//                      These are conditional, only defined if better versions
+//                      were not available for the platform.
+//
+//                      These versions are platform neutral.
+//
+//--------------------------------------------------------------------------------
+
+#if defined U_NO_PLATFORM_ATOMICS
 static UMutex   gIncDecMutex = U_MUTEX_INITIALIZER;
-#endif
 
-U_CAPI int32_t U_EXPORT2
+U_INTERNAL int32_t U_EXPORT2
 umtx_atomic_inc(int32_t *p)  {
     int32_t retVal;
-    if (pIncFn) {
-        retVal = (*pIncFn)(gIncDecContext, p);
-    } else {
-        #if U_PLATFORM_HAS_WIN32_API
-            retVal = InterlockedIncrement((LONG*)p);
-        #elif defined(USE_MAC_OS_ATOMIC_INCREMENT)
-            retVal = OSAtomicIncrement32Barrier(p);
-        #elif (U_HAVE_GCC_ATOMICS == 1)
-            retVal = __sync_add_and_fetch(p, 1);
-        #elif defined (POSIX)
-            umtx_lock(&gIncDecMutex);
-            retVal = ++(*p);
-            umtx_unlock(&gIncDecMutex);
-        #else
-            /* Unknown Platform. */
-            retVal = ++(*p);
-        #endif
-    }
+    umtx_lock(&gIncDecMutex);
+    retVal = ++(*p);
+    umtx_unlock(&gIncDecMutex);
     return retVal;
 }
 
-U_CAPI int32_t U_EXPORT2
+
+U_INTERNAL int32_t U_EXPORT2
 umtx_atomic_dec(int32_t *p) {
     int32_t retVal;
-    if (pDecFn) {
-        retVal = (*pDecFn)(gIncDecContext, p);
-    } else {
-        #if U_PLATFORM_HAS_WIN32_API
-            retVal = InterlockedDecrement((LONG*)p);
-        #elif defined(USE_MAC_OS_ATOMIC_INCREMENT)
-            retVal = OSAtomicDecrement32Barrier(p);
-        #elif (U_HAVE_GCC_ATOMICS == 1)
-            retVal = __sync_sub_and_fetch(p, 1);
-        #elif defined (POSIX)
-            umtx_lock(&gIncDecMutex);
-            retVal = --(*p);
-            umtx_unlock(&gIncDecMutex);
-        #else
-            /* Unknown Platform. */
-            retVal = --(*p);
-        #endif
-    }
+    umtx_lock(&gIncDecMutex);
+    retVal = --(*p);
+    umtx_unlock(&gIncDecMutex);
     return retVal;
 }
 
+U_INTERNAL int32_t U_EXPORT2
+umtx_loadAcquire(atomic_int32_t &var) {
+    int32_t val = var;
+    umtx_lock(&gIncDecMutex);
+    umtx_unlock(&gIncDecMutex);
+    return val;
+}
 
+U_INTERNAL void U_EXPORT2
+umtx_storeRelease(atomic_int32_t &var, int32_t val) {
+    umtx_lock(&gIncDecMutex);
+    umtx_unlock(&gIncDecMutex);
+    var = val;
+}
 
-U_CAPI void U_EXPORT2
-u_setAtomicIncDecFunctions(const void *context, UMtxAtomicFn *ip, UMtxAtomicFn *dp,
-                                UErrorCode *status) {
-    if (U_FAILURE(*status)) {
-        return;
-    }
-    /* Can not set a mutex function to a NULL value  */
-    if (ip==NULL || dp==NULL) {
-        *status = U_ILLEGAL_ARGUMENT_ERROR;
-        return;
-    }
-    /* If ICU is not in an initial state, disallow this operation. */
-    if (cmemory_inUse()) {
-        *status = U_INVALID_STATE_ERROR;
-        return;
-    }
+#endif
+
+//--------------------------------------------------------------------------
+//
+//  Deprecated functions for setting user mutexes.
+//
+//--------------------------------------------------------------------------
 
-    pIncFn = ip;
-    pDecFn = dp;
-    gIncDecContext = context;
-
-#if U_DEBUG
-    {
-        int32_t   testInt = 0;
-        U_ASSERT(umtx_atomic_inc(&testInt) == 1);     /* Sanity Check.    Do the functions work at all? */
-        U_ASSERT(testInt == 1);
-        U_ASSERT(umtx_atomic_dec(&testInt) == 0);
-        U_ASSERT(testInt == 0);
+U_DEPRECATED void U_EXPORT2 
+u_setMutexFunctions(const void * /*context */, UMtxInitFn *, UMtxFn *, 
+                    UMtxFn *,  UMtxFn *, UErrorCode *status) {
+    if (U_SUCCESS(*status)) {
+        *status = U_UNSUPPORTED_ERROR;
     }
-#endif
+    return;
 }
 
 
-/*
- *  Mutex Cleanup Function
- *      Reset the mutex function callback pointers.
- *      Called from the global ICU u_cleanup() function.
- */
-U_CFUNC UBool umtx_cleanup(void) {
-    /* Extra, do-nothing function call to suppress compiler warnings on platforms where
-     *   mutexed_compare_and_swap is not otherwise used.  */
-    void *pv = &globalMutex;
-    mutexed_compare_and_swap(&pv, NULL, NULL);
-    usrMutexCleanup();
-           
-    pIncFn          = NULL;
-    pDecFn          = NULL;
-    gIncDecContext  = NULL;
-
-    return TRUE;
+
+U_DEPRECATED void U_EXPORT2
+u_setAtomicIncDecFunctions(const void * /*context */, UMtxAtomicFn *, UMtxAtomicFn *,
+                           UErrorCode *status) {
+    if (U_SUCCESS(*status)) {
+        *status = U_UNSUPPORTED_ERROR;
+    }
+    return;
 }
+
index 893de8e6336edd562119dc32d5af409cce7895d8..4a6a89705b7e9a2b1163c8409c8ebbee18b5e4ab 100644 (file)
@@ -1,6 +1,6 @@
 /*
 **********************************************************************
-*   Copyright (C) 1997-2012, International Business Machines
+*   Copyright (C) 1997-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *
 #include "unicode/uclean.h"
 #include "putilimp.h"
 
-/* For _ReadWriteBarrier(). */
-#if defined(_MSC_VER) && _MSC_VER >= 1500
-# include <intrin.h>
-#endif
 
-/* For CRITICAL_SECTION */
-#if U_PLATFORM_HAS_WIN32_API
-#if 0  
-/* TODO(andy): Why doesn't windows.h compile in all files? It does in some.
- *             The intent was to include windows.h here, and have struct UMutex
- *             have an embedded CRITICAL_SECTION when building on Windows.
- *             The workaround is to put some char[] storage in UMutex instead,
- *             avoiding the need to include windows.h everwhere this header is included.
- */
+
+// Forward Declarations
+struct UMutex;
+struct UInitOnce;
+
+
+/****************************************************************************
+ *
+ *   Low Level Atomic Operations. 
+ *      Compiler dependent. Not operating system dependent.
+ *
+ ****************************************************************************/
+#if U_HAVE_STD_ATOMICS
+
+//  C++11 atomics are available.
+
+#include <atomic>
+
+typedef std::atomic<int32_t> atomic_int32_t;
+#define ATOMIC_INT32_T_INITIALIZER(val) ATOMIC_VAR_INIT(val)
+
+inline int32_t umtx_loadAcquire(atomic_int32_t &var) {
+    return var.load(std::memory_order_acquire);
+};
+
+inline void umtx_storeRelease(atomic_int32_t &var, int32_t val) {
+    var.store(val, std::memory_order_release);
+};
+
+inline int32_t umtx_atomic_inc(atomic_int32_t *var) {
+    return var->fetch_add(1) + 1;
+}
+     
+inline int32_t umtx_atomic_dec(atomic_int32_t *var) {
+    return var->fetch_sub(1) - 1;
+}
+     
+
+#elif U_PLATFORM_HAS_WIN32_API
+
+// MSVC compiler. Reads and writes of volatile variables have
+//                acquire and release memory semantics, respectively.
+//                This is a Microsoft extension, not standard C++ behavior.
+//
+//   Update:      can't use this because of MinGW, built with gcc.
+//                Original plan was to use gcc atomics for MinGW, but they
+//                aren't supported, so we fold MinGW into this path.
+
 # define WIN32_LEAN_AND_MEAN
 # define VC_EXTRALEAN
 # define NOUSER
 # define NOSERVICE
 # define NOIME
 # define NOMCX
+# ifndef NOMINMAX
+# define NOMINMAX
+# endif
 # include <windows.h>
-#endif  /* 0 */
-#define U_WINDOWS_CRIT_SEC_SIZE 64
-#endif  /* win32 */
-
-#if U_PLATFORM_IS_DARWIN_BASED
-#if defined(__STRICT_ANSI__)
-#define UPRV_REMAP_INLINE
-#define inline
-#endif
-#include <libkern/OSAtomic.h>
-#define USE_MAC_OS_ATOMIC_INCREMENT 1
-#if defined(UPRV_REMAP_INLINE)
-#undef inline
-#undef UPRV_REMAP_INLINE
-#endif
-#endif
 
+typedef volatile LONG atomic_int32_t;
+#define ATOMIC_INT32_T_INITIALIZER(val) val
+
+#ifdef __cplusplus
+inline int32_t umtx_loadAcquire(atomic_int32_t &var) {
+    return InterlockedCompareExchange(&var, 0, 0);
+}
+
+inline void umtx_storeRelease(atomic_int32_t &var, int32_t val) {
+    InterlockedExchange(&var, val);
+}
+
+
+inline int32_t umtx_atomic_inc(atomic_int32_t *var) {
+    return InterlockedIncrement(var);
+}
+
+inline int32_t umtx_atomic_dec(atomic_int32_t *var) {
+    return InterlockedDecrement(var);
+}
+#endif /* __cplusplus */
+
+
+
+#elif U_HAVE_GCC_ATOMICS
 /*
- * If we do not compile with dynamic_annotations.h then define
- * empty annotation macros.
- *  See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations
+ * gcc atomic ops. These are available on several other compilers as well.
  */
-#ifndef ANNOTATE_HAPPENS_BEFORE
-# define ANNOTATE_HAPPENS_BEFORE(obj)
-# define ANNOTATE_HAPPENS_AFTER(obj)
-# define ANNOTATE_UNPROTECTED_READ(x) (x)
-#endif
+typedef int32_t atomic_int32_t;
+#define ATOMIC_INT32_T_INITIALIZER(val) val
 
-#ifndef UMTX_FULL_BARRIER
-# if U_HAVE_GCC_ATOMICS
-#  define UMTX_FULL_BARRIER __sync_synchronize();
-# elif defined(_MSC_VER) && _MSC_VER >= 1500
-    /* From MSVC intrin.h. Use _ReadWriteBarrier() only on MSVC 9 and higher. */
-#  define UMTX_FULL_BARRIER _ReadWriteBarrier();
-# elif U_PLATFORM_IS_DARWIN_BASED
-#  define UMTX_FULL_BARRIER OSMemoryBarrier();
-# else
-#  define UMTX_FULL_BARRIER \
-    { \
-        umtx_lock(NULL); \
-        umtx_unlock(NULL); \
-    }
-# endif
-#endif
+#ifdef __cplusplus
+inline int32_t umtx_loadAcquire(atomic_int32_t &var) {
+    int32_t val = var;
+    __sync_synchronize();
+    return val;
+}
 
-#ifndef UMTX_ACQUIRE_BARRIER
-# define UMTX_ACQUIRE_BARRIER UMTX_FULL_BARRIER
-#endif
+inline void umtx_storeRelease(atomic_int32_t &var, int32_t val) {
+    __sync_synchronize();
+    var = val;
+}
 
-#ifndef UMTX_RELEASE_BARRIER
-# define UMTX_RELEASE_BARRIER UMTX_FULL_BARRIER
-#endif
+inline int32_t umtx_atomic_inc(atomic_int32_t *p)  {
+   return __sync_add_and_fetch(p, 1);
+}
+
+inline int32_t umtx_atomic_dec(atomic_int32_t *p)  {
+   return __sync_sub_and_fetch(p, 1);
+}
+
+#endif /* __cplusplus */
+
+#else
 
-/**
- * \def UMTX_CHECK
- * Encapsulates a safe check of an expression
- * for use with double-checked lazy inititialization.
- * Either memory barriers or mutexes are required, to prevent both the hardware
- * and the compiler from reordering operations across the check.
- * The expression must involve only a  _single_ variable, typically
- *    a possibly null pointer or a boolean that indicates whether some service
- *    is initialized or not.
- * The setting of the variable involved in the test must be the last step of
- *    the initialization process.
- *
- * @internal
- */
-#define UMTX_CHECK(pMutex, expression, result) \
-    { \
-        (result)=(expression); \
-        UMTX_ACQUIRE_BARRIER; \
-    }
 /*
- * TODO: Replace all uses of UMTX_CHECK and surrounding code
- * with SimpleSingleton or TriStateSingleton, and remove UMTX_CHECK.
+ * Unknown Platform. Use out-of-line functions, which in turn use mutexes.
+ *                   Slow but correct.
  */
 
-/*
- * Code within ICU that accesses shared static or global data should
- * instantiate a Mutex object while doing so.  The unnamed global mutex
- * is used throughout ICU, so keep locking short and sweet.
+#define U_NO_PLATFORM_ATOMICS
+
+typedef int32_t atomic_int32_t;
+#define ATOMIC_INT32_T_INITIALIZER(val) val
+
+#ifdef __cplusplus
+U_INTERNAL int32_t U_EXPORT2 umtx_loadAcquire(atomic_int32_t &var);
+
+U_INTERNAL void U_EXPORT2 umtx_storeRelease(atomic_int32_t &var, int32_t val);
+#endif /* __cplusplus */
+
+U_INTERNAL int32_t U_EXPORT2 umtx_atomic_inc(atomic_int32_t *p);
+
+U_INTERNAL int32_t U_EXPORT2 umtx_atomic_dec(atomic_int32_t *p);
+
+#endif  /* Low Level Atomic Ops Platfrom Chain */
+
+
+
+/*************************************************************************************************
+ *
+ *  UInitOnce Definitions.
+ *     These are platform neutral.
  *
- * For example:
+ *************************************************************************************************/
+
+struct UInitOnce {
+    atomic_int32_t   fState;
+    UErrorCode       fErrCode;
+#ifdef __cplusplus
+    void reset() {fState = 0; fState=0;};
+    UBool isReset() {return umtx_loadAcquire(fState) == 0;};
+// Note: isReset() is used by service registration code.
+//                 Thread safety of this usage needs review.
+#endif
+};
+typedef struct UInitOnce UInitOnce;
+#define U_INITONCE_INITIALIZER {ATOMIC_INT32_T_INITIALIZER(0), U_ZERO_ERROR}
+
+#ifdef __cplusplus
+// TODO: get all ICU files using umutex converted to C++,
+//       then remove the __cpluplus conditionals from this file.
+
+U_CAPI UBool U_EXPORT2 umtx_initImplPreInit(UInitOnce &);
+U_CAPI void  U_EXPORT2 umtx_initImplPostInit(UInitOnce &, UBool success);
+
+template<class T> void umtx_initOnce(UInitOnce &uio, T *obj, void (T::*fp)()) {
+    if (umtx_loadAcquire(uio.fState) == 2) {
+        return;
+    }
+    if (umtx_initImplPreInit(uio)) {
+        (obj->*fp)();
+        umtx_initImplPostInit(uio, TRUE);
+    }
+}
+
+
+// umtx_initOnce variant for plain functions, or static class functions.
+//               No context parameter.
+inline void umtx_initOnce(UInitOnce &uio, void (*fp)()) {
+    if (umtx_loadAcquire(uio.fState) == 2) {
+        return;
+    }
+    if (umtx_initImplPreInit(uio)) {
+        (*fp)();
+        umtx_initImplPostInit(uio, TRUE);
+    }
+}
+
+// umtx_initOnce variant for plain functions, or static class functions.
+//               With ErrorCode, No context parameter.
+inline void umtx_initOnce(UInitOnce &uio, void (*fp)(UErrorCode &), UErrorCode &errCode) {
+    if (U_FAILURE(errCode)) {
+        return;
+    }    
+    if (umtx_loadAcquire(uio.fState) != 2 && umtx_initImplPreInit(uio)) {
+        // We run the initialization.
+        (*fp)(errCode);
+        uio.fErrCode = errCode;
+        umtx_initImplPostInit(uio, TRUE);
+    } else {
+        // Someone else already ran the initialization.
+        if (U_FAILURE(uio.fErrCode)) {
+            errCode = uio.fErrCode;
+        }
+    }
+}
+
+// umtx_initOnce variant for plain functions, or static class functions,
+//               with a context parameter.
+template<class T> void umtx_initOnce(UInitOnce &uio, void (*fp)(T), T context) {
+    if (umtx_loadAcquire(uio.fState) == 2) {
+        return;
+    }
+    if (umtx_initImplPreInit(uio)) {
+        (*fp)(context);
+        umtx_initImplPostInit(uio, TRUE);
+    }
+}
+
+// umtx_initOnce variant for plain functions, or static class functions,
+//               with a context parameter and an error code.
+template<class T> void umtx_initOnce(UInitOnce &uio, void (*fp)(T, UErrorCode &), T context, UErrorCode &errCode) {
+    if (U_FAILURE(errCode)) {
+        return;
+    }    
+    if (umtx_loadAcquire(uio.fState) != 2 && umtx_initImplPreInit(uio)) {
+        // We run the initialization.
+        (*fp)(context, errCode);
+        uio.fErrCode = errCode;
+        umtx_initImplPostInit(uio, TRUE);
+    } else {
+        // Someone else already ran the initialization.
+        if (U_FAILURE(uio.fErrCode)) {
+            errCode = uio.fErrCode;
+        }
+    }
+}
+
+#endif /*  __cplusplus */
+
+
+
+/*************************************************************************************************
  *
- * void Function(int arg1, int arg2)
- * {
- *   static Object* foo;     // Shared read-write object
- *   umtx_lock(NULL);        // Lock the ICU global mutex
- *   foo->Method();
- *   umtx_unlock(NULL);
- * }
+ *  Mutex Definitions. Platform Dependent, #if platform chain follows.
+ *         TODO:  Add a C++11 version.
+ *                Need to convert all mutex using files to C++ first.
  *
- * an alternative C++ mutex API is defined in the file common/mutex.h
- */
+ *************************************************************************************************/
 
-/*
- * UMutex - Mutexes for use by ICU implementation code.
- *          Must be declared as static or globals. They cannot appear as members
- *          of other objects.
- *          UMutex structs must be initialized.
- *          Example:
- *            static UMutex = U_MUTEX_INITIALIZER;
- *          The declaration of struct UMutex is platform dependent.
+#if U_PLATFORM_HAS_WIN32_API
+
+/* Windows Definitions.
+ *    Windows comes first in the platform chain.
+ *    Cygwin (and possibly others) have both WIN32 and POSIX APIs. Prefer Win32 in this case.
  */
 
 
-#if U_PLATFORM_HAS_WIN32_API
+/* For CRITICAL_SECTION */
 
-/*  U_INIT_ONCE mimics the windows API INIT_ONCE, which exists on Windows Vista and newer.
- *  When ICU no longer needs to support older Windows platforms (XP) that do not have
- * a native INIT_ONCE, switch this implementation over to wrap the native Windows APIs.
+/*
+ *   Note: there is an earlier include of windows.h in this file, but it is in 
+ *         different conditionals.
+ *         This one is needed if we are using C++11 for atomic ops, but
+ *         win32 APIs for Critical Sections.
  */
-typedef struct U_INIT_ONCE {
-    long               fState;
-    void              *fContext;
-} U_INIT_ONCE;
-#define U_INIT_ONCE_STATIC_INIT {0, NULL}
+# define WIN32_LEAN_AND_MEAN
+# define VC_EXTRALEAN
+# define NOUSER
+# define NOSERVICE
+# define NOIME
+# define NOMCX
+# ifndef NOMINMAX
+# define NOMINMAX
+# endif
+# include <windows.h>
+
 
 typedef struct UMutex {
-    U_INIT_ONCE       fInitOnce;
-    UMTX              fUserMutex;
-    UBool             fInitialized;  /* Applies to fUserMutex only. */
-    /* CRITICAL_SECTION  fCS; */  /* See note above. Unresolved problems with including
-                                   * Windows.h, which would allow using CRITICAL_SECTION
-                                   * directly here. */
-    char              fCS[U_WINDOWS_CRIT_SEC_SIZE];
+    UInitOnce         fInitOnce;
+    CRITICAL_SECTION  fCS;
 } UMutex;
 
 /* Initializer for a static UMUTEX. Deliberately contains no value for the
  *  CRITICAL_SECTION.
  */
-#define U_MUTEX_INITIALIZER {U_INIT_ONCE_STATIC_INIT, NULL, FALSE}
+#define U_MUTEX_INITIALIZER {U_INITONCE_INITIALIZER}
+
+
 
 #elif U_PLATFORM_IMPLEMENTS_POSIX
+
+/*
+ *  POSIX platform
+ */
+
 #include <pthread.h>
 
 struct UMutex {
     pthread_mutex_t  fMutex;
-    UMTX             fUserMutex;
-    UBool            fInitialized;
 };
-#define U_MUTEX_INITIALIZER  {PTHREAD_MUTEX_INITIALIZER, NULL, FALSE}
+typedef struct UMutex UMutex;
+#define U_MUTEX_INITIALIZER  {PTHREAD_MUTEX_INITIALIZER}
+
 
 #else
-/* Unknow platform type. */
-struct UMutex {
-    void *fMutex;
-};
-#define U_MUTEX_INITIALIZER {NULL}
+
+/* 
+ *  Unknow platform type. 
+ *      This is an error condition. ICU requires mutexes.
+ */
+
 #error Unknown Platform.
 
 #endif
 
-#if (U_PLATFORM != U_PF_CYGWIN && U_PLATFORM != U_PF_MINGW) || defined(CYGWINMSVC)
-typedef struct UMutex UMutex;
-#endif
+
     
+/**************************************************************************************
+ *
+ *  Mutex Implementation function declaratations.
+ *     Declarations are platform neutral.
+ *     Implementations, in umutex.cpp, are platform specific.
+ *
+ ************************************************************************************/
+
 /* Lock a mutex.
  * @param mutex The given mutex to be locked.  Pass NULL to specify
  *              the global ICU mutex.  Recursive locks are an error
  *              and may cause a deadlock on some platforms.
  */
-U_CAPI void U_EXPORT2 umtx_lock(UMutex* mutex); 
+U_INTERNAL void U_EXPORT2 umtx_lock(UMutex* mutex); 
 
 /* Unlock a mutex.
  * @param mutex The given mutex to be unlocked.  Pass NULL to specify
  *              the global ICU mutex.
  */
-U_CAPI void U_EXPORT2 umtx_unlock (UMutex* mutex);
-
-/*
- * Atomic Increment and Decrement of an int32_t value.
- *
- * Return Values:
- *   If the result of the operation is zero, the return zero.
- *   If the result of the operation is not zero, the sign of returned value
- *      is the same as the sign of the result, but the returned value itself may
- *      be different from the result of the operation.
- */
-U_CAPI int32_t U_EXPORT2 umtx_atomic_inc(int32_t *);
-U_CAPI int32_t U_EXPORT2 umtx_atomic_dec(int32_t *);
+U_INTERNAL void U_EXPORT2 umtx_unlock (UMutex* mutex);
 
-#endif /*_CMUTEX*/
+#endif /* UMUTEX_H */
 /*eof*/
index 932d2024968c5603e00bc87c7e1c323a69a090d4..eafe70ccb8a45de7e60a3a136bbb07bbd25e0bbd 100644 (file)
@@ -1,7 +1,7 @@
 /*
 ******************************************************************************
 *
-*   Copyright (C) 1999-2011, International Business Machines
+*   Copyright (C) 1999-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
@@ -20,6 +20,7 @@
 #include "unicode/udata.h"
 #include "unicode/utf.h"
 #include "unicode/utf16.h"
+#include "uassert.h"
 #include "ustr_imp.h"
 #include "umutex.h"
 #include "cmemory.h"
@@ -102,7 +103,7 @@ typedef struct {
 
 static UDataMemory *uCharNamesData=NULL;
 static UCharNames *uCharNames=NULL;
-static UErrorCode gLoadErrorCode=U_ZERO_ERROR;
+static UInitOnce  gCharNamesInitOnce = U_INITONCE_INITIALIZER;
 
 /*
  * Maximum length of character names (regular & 1.0).
@@ -168,6 +169,7 @@ static UBool U_CALLCONV unames_cleanup(void)
     if(uCharNames) {
         uCharNames = NULL;
     }
+    gCharNamesInitOnce.reset();
     gMaxNameLength=0;
     return TRUE;
 }
@@ -187,52 +189,25 @@ isAcceptable(void * /*context*/,
         pInfo->formatVersion[0]==1);
 }
 
-static UBool
-isDataLoaded(UErrorCode *pErrorCode) {
-    /* load UCharNames from file if necessary */
-    UBool isCached;
-
-    /* do this because double-checked locking is broken */
-    UMTX_CHECK(NULL, (uCharNames!=NULL), isCached);
-
-    if(!isCached) {
-        UCharNames *names;
-        UDataMemory *data;
-
-        /* check error code from previous attempt */
-        if(U_FAILURE(gLoadErrorCode)) {
-            *pErrorCode=gLoadErrorCode;
-            return FALSE;
-        }
-
-        /* open the data outside the mutex block */
-        data=udata_openChoice(NULL, DATA_TYPE, DATA_NAME, isAcceptable, NULL, pErrorCode);
-        if(U_FAILURE(*pErrorCode)) {
-            gLoadErrorCode=*pErrorCode;
-            return FALSE;
-        }
+static void U_CALLCONV
+loadCharNames(UErrorCode &status) {
+    U_ASSERT(uCharNamesData == NULL);
+    U_ASSERT(uCharNames == NULL);
 
-        names=(UCharNames *)udata_getMemory(data);
+    uCharNamesData = udata_openChoice(NULL, DATA_TYPE, DATA_NAME, isAcceptable, NULL, &status);
+    if(U_FAILURE(status)) {
+        uCharNamesData = NULL;
+    } else {
+        uCharNames = (UCharNames *)udata_getMemory(uCharNamesData);
+    }
+    ucln_common_registerCleanup(UCLN_COMMON_UNAMES, unames_cleanup);
+}
 
-        /* in the mutex block, set the data for this process */
-        {
-            umtx_lock(NULL);
-            if(uCharNames==NULL) {
-                uCharNamesData=data;
-                uCharNames=names;
-                data=NULL;
-                names=NULL;
-                ucln_common_registerCleanup(UCLN_COMMON_UNAMES, unames_cleanup);
-            }
-            umtx_unlock(NULL);
-        }
 
-        /* if a different thread set it first, then close the extra data */
-        if(data!=NULL) {
-            udata_close(data); /* NULL if it was set correctly */
-        }
-    }
-    return TRUE;
+static UBool
+isDataLoaded(UErrorCode *pErrorCode) {
+    umtx_initOnce(gCharNamesInitOnce, &loadCharNames, *pErrorCode);
+    return U_SUCCESS(*pErrorCode);
 }
 
 #define WRITE_CHAR(buffer, bufferLength, bufferPos, c) { \
index e43cae7bf07be991c2c47afc6351be89b8ca50ef..c406183b105fd4d9490cfe3c88a5a541018c0937 100644 (file)
@@ -43,6 +43,9 @@
 
 U_NAMESPACE_BEGIN
 
+// Forward Declarations
+void U_CALLCONV locale_available_init();
+
 /**
  * A <code>Locale</code> object represents a specific geographical, political,
  * or cultural region. An operation that requires a <code>Locale</code> to perform
@@ -738,6 +741,8 @@ private:
      * @internal
      */
     friend Locale *locale_set_default_internal(const char *, UErrorCode& status);
+
+    friend void locale_available_init();
 };
 
 inline UBool
index 86e38773316390ef575bd337445a4010096dc030..6e3c1b2afc017ed210efb0024d9460bb96ab51bb 100644 (file)
@@ -1,7 +1,7 @@
 /*
 ******************************************************************************
 *
-*   Copyright (C) 1996-2011, International Business Machines Corporation
+*   Copyright (C) 1996-2013, International Business Machines Corporation
 *   and others.  All Rights Reserved.
 *
 ******************************************************************************
@@ -484,7 +484,6 @@ private:
     UResourceBundle *fResource;
     void constructForLocale(const UnicodeString& path, const Locale& locale, UErrorCode& error);
     Locale *fLocale;
-
 };
 
 U_NAMESPACE_END
index c9445943a4a1ff142bd8d5fd2f5f9065e28e5ba0..b29571d4adbbdd9d6d832aaeb0f9768b24161a56 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2009-2012, International Business Machines
+// Copyright (C) 2009-2013, International Business Machines
 // Corporation and others. All Rights Reserved.
 //
 // Copyright 2001 and onwards Google Inc.
@@ -183,7 +183,7 @@ class U_COMMON_API StringPiece : public UMemory {
    * Maximum integer, used as a default value for substring methods.
    * @stable ICU 4.2
    */
-  static const int32_t npos = 0x7fffffff;
+  static const int32_t npos; // = 0x7fffffff;
 
   /**
    * Returns a substring of this StringPiece.
index 87809f0e687f30b3caafdeee605c8026b23d4d83..0e2e9367ea371097019c0d5ad34af342fe8a2622 100644 (file)
@@ -1,6 +1,6 @@
 /*
 ******************************************************************************
-* Copyright (C) 2001-2012, International Business Machines
+* Copyright (C) 2001-2013, International Business Machines
 *                Corporation and others. All Rights Reserved.
 ******************************************************************************
 *   file name:  uclean.h
@@ -100,13 +100,71 @@ U_STABLE void U_EXPORT2
 u_cleanup(void);
 
 
+/**
+  *  Pointer type for a user supplied memory allocation function.
+  *  @param context user supplied value, obtained from from u_setMemoryFunctions().
+  *  @param size    The number of bytes to be allocated
+  *  @return        Pointer to the newly allocated memory, or NULL if the allocation failed.
+  *  @stable ICU 2.8
+  *  @system
+  */
+typedef void *U_CALLCONV UMemAllocFn(const void *context, size_t size);
+/**
+  *  Pointer type for a user supplied memory re-allocation function.
+  *  @param context user supplied value, obtained from from u_setMemoryFunctions().
+  *  @param size    The number of bytes to be allocated
+  *  @return        Pointer to the newly allocated memory, or NULL if the allocation failed.
+  *  @stable ICU 2.8
+  *  @system
+  */
+typedef void *U_CALLCONV UMemReallocFn(const void *context, void *mem, size_t size);
+/**
+  *  Pointer type for a user supplied memory free  function.  Behavior should be
+  *  similar the standard C library free().
+  *  @param context user supplied value, obtained from from u_setMemoryFunctions().
+  *  @param mem     Pointer to the memory block to be resized
+  *  @param size    The new size for the block
+  *  @return        Pointer to the resized memory block, or NULL if the resizing failed.
+  *  @stable ICU 2.8
+  *  @system
+  */
+typedef void  U_CALLCONV UMemFreeFn (const void *context, void *mem);
+
+/**
+ *  Set the functions that ICU will use for memory allocation.
+ *  Use of this function is optional; by default (without this function), ICU will
+ *  use the standard C library malloc() and free() functions.
+ *  This function can only be used when ICU is in an initial, unused state, before
+ *  u_init() has been called.
+ *  @param context This pointer value will be saved, and then (later) passed as
+ *                 a parameter to the memory functions each time they
+ *                 are called.
+ *  @param a       Pointer to a user-supplied malloc function.
+ *  @param r       Pointer to a user-supplied realloc function.
+ *  @param f       Pointer to a user-supplied free function.
+ *  @param status  Receives error values.
+ *  @stable ICU 2.8
+ *  @system
+ */  
+U_STABLE void U_EXPORT2 
+u_setMemoryFunctions(const void *context, UMemAllocFn *a, UMemReallocFn *r, UMemFreeFn *f, 
+                    UErrorCode *status);
 
 
+/*********************************************************************************
+ *
+ * Deprecated Functions
+ *
+ *    The following functions for user supplied mutexes are no longer supported.
+ *    Any attempt to use them will return a U_UNSUPPORTED_ERROR.
+ *
+ **********************************************************************************/
+
 /**
   * An opaque pointer type that represents an ICU mutex.
   * For user-implemented mutexes, the value will typically point to a
   *  struct or object that implements the mutex.
-  * @stable ICU 2.8
+  * @deprecated ICU 52. This type is no longer supported.
   * @system
   */
 typedef void *UMTX;
@@ -124,7 +182,7 @@ typedef void *UMTX;
   *                 identify the mutex by the UMTX value.
   *  @param status  Error status.  Report errors back to ICU by setting this variable
   *                 with an error code.
-  *  @stable ICU 2.8
+  *  @deprecated ICU 52. This function is no longer supported.
   *  @system
   */
 typedef void U_CALLCONV UMtxInitFn (const void *context, UMTX  *mutex, UErrorCode* status);
@@ -136,7 +194,7 @@ typedef void U_CALLCONV UMtxInitFn (const void *context, UMTX  *mutex, UErrorCod
   *  whenever ICU needs to lock, unlock, or destroy a mutex.
   *  @param context user supplied value, obtained from from u_setMutexFunctions().
   *  @param mutex   specify the mutex on which to operate.
-  *  @stable ICU 2.8
+  *  @deprecated ICU 52. This function is no longer supported.
   *  @system
   */
 typedef void U_CALLCONV UMtxFn   (const void *context, UMTX  *mutex);
@@ -156,10 +214,10 @@ typedef void U_CALLCONV UMtxFn   (const void *context, UMTX  *mutex);
   *  @param lock    pointer to the mutex lock function.  Must be non-null.
   *  @param unlock  Pointer to the mutex unlock function.  Must be non-null.
   *  @param status  Receives error values.
-  *  @stable ICU 2.8
+  *  @deprecated ICU 52. This function is no longer supported.
   *  @system
   */  
-U_STABLE void U_EXPORT2 
+U_DEPRECATED void U_EXPORT2 
 u_setMutexFunctions(const void *context, UMtxInitFn *init, UMtxFn *destroy, UMtxFn *lock, UMtxFn *unlock,
                     UErrorCode *status);
 
@@ -169,7 +227,7 @@ u_setMutexFunctions(const void *context, UMtxInitFn *init, UMtxFn *destroy, UMtx
   *  @param context user supplied value, obtained from from u_setAtomicIncDecFunctions().
   *  @param p   Pointer to a 32 bit int to be incremented or decremented
   *  @return    The value of the variable after the inc or dec operation.
-  *  @stable ICU 2.8
+  *  @deprecated ICU 52. This function is no longer supported.
   *  @system
   */
 typedef int32_t U_CALLCONV UMtxAtomicFn(const void *context, int32_t *p);
@@ -186,64 +244,13 @@ typedef int32_t U_CALLCONV UMtxAtomicFn(const void *context, int32_t *p);
  *  @param inc     Pointer to a function to do an atomic increment operation.  Must be non-null.
  *  @param dec     Pointer to a function to do an atomic decrement operation.  Must be non-null.
  *  @param status  Receives error values.
- *  @stable ICU 2.8
+ *  @deprecated ICU 52. This function is no longer supported.
  *  @system
  */  
-U_STABLE void U_EXPORT2 
+U_DEPRECATED void U_EXPORT2 
 u_setAtomicIncDecFunctions(const void *context, UMtxAtomicFn *inc, UMtxAtomicFn *dec,
                     UErrorCode *status);
 
-
-
-/**
-  *  Pointer type for a user supplied memory allocation function.
-  *  @param context user supplied value, obtained from from u_setMemoryFunctions().
-  *  @param size    The number of bytes to be allocated
-  *  @return        Pointer to the newly allocated memory, or NULL if the allocation failed.
-  *  @stable ICU 2.8
-  *  @system
-  */
-typedef void *U_CALLCONV UMemAllocFn(const void *context, size_t size);
-/**
-  *  Pointer type for a user supplied memory re-allocation function.
-  *  @param context user supplied value, obtained from from u_setMemoryFunctions().
-  *  @param size    The number of bytes to be allocated
-  *  @return        Pointer to the newly allocated memory, or NULL if the allocation failed.
-  *  @stable ICU 2.8
-  *  @system
-  */
-typedef void *U_CALLCONV UMemReallocFn(const void *context, void *mem, size_t size);
-/**
-  *  Pointer type for a user supplied memory free  function.  Behavior should be
-  *  similar the standard C library free().
-  *  @param context user supplied value, obtained from from u_setMemoryFunctions().
-  *  @param mem     Pointer to the memory block to be resized
-  *  @param size    The new size for the block
-  *  @return        Pointer to the resized memory block, or NULL if the resizing failed.
-  *  @stable ICU 2.8
-  *  @system
-  */
-typedef void  U_CALLCONV UMemFreeFn (const void *context, void *mem);
-
-/**
- *  Set the functions that ICU will use for memory allocation.
- *  Use of this function is optional; by default (without this function), ICU will
- *  use the standard C library malloc() and free() functions.
- *  This function can only be used when ICU is in an initial, unused state, before
- *  u_init() has been called.
- *  @param context This pointer value will be saved, and then (later) passed as
- *                 a parameter to the memory functions each time they
- *                 are called.
- *  @param a       Pointer to a user-supplied malloc function.
- *  @param r       Pointer to a user-supplied realloc function.
- *  @param f       Pointer to a user-supplied free function.
- *  @param status  Receives error values.
- *  @stable ICU 2.8
- *  @system
- */  
-U_STABLE void U_EXPORT2 
-u_setMemoryFunctions(const void *context, UMemAllocFn *a, UMemReallocFn *r, UMemFreeFn *f, 
-                    UErrorCode *status);
 #endif  /* U_HIDE_SYSTEM_API */
 
 #endif
index 477de86076d4d633e951e6b048ff06e915a0df8a..fa0b4b3775530b95211178c59c07c44fb5131608 100644 (file)
@@ -1,6 +1,6 @@
 /*
 ***************************************************************************
-* Copyright (C) 1999-2011, International Business Machines Corporation
+* Copyright (C) 1999-2013, International Business Machines Corporation
 * and others. All Rights Reserved.
 ***************************************************************************
 *   Date        Name        Description
@@ -22,6 +22,9 @@
 
 U_NAMESPACE_BEGIN
 
+// Forward Declarations.
+void UnicodeSet_initInclusion(int32_t src, UErrorCode &status);
+
 class BMPSet;
 class ParsePosition;
 class RBBIRuleScanner;
@@ -1586,6 +1589,7 @@ private:
                               UnicodeString& rebuiltPat,
                               UErrorCode& ec);
 
+    friend void UnicodeSet_initInclusion(int32_t src, UErrorCode &status);
     static const UnicodeSet* getInclusions(int32_t src, UErrorCode &status);
 
     /**
index 6795efa569ac743e8c04253ef6b9b599080e4e89..b9151534782ecd7b8e25449160acfda5a9b0d02f 100644 (file)
@@ -1,7 +1,7 @@
 /*
 *******************************************************************************
 *
-*   Copyright (C) 1999-2012, International Business Machines
+*   Copyright (C) 1999-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
@@ -127,7 +127,11 @@ private:
 
 U_CDECL_BEGIN
 
-static UnicodeSet *INCLUSIONS[UPROPS_SRC_COUNT] = { NULL }; // cached getInclusions()
+struct Inclusion {
+    UnicodeSet  *fSet;
+    UInitOnce    fInitOnce;
+};
+static Inclusion gInclusions[UPROPS_SRC_COUNT]; // cached getInclusions()
 
 STATIC_SIMPLE_SINGLETON(uni32Singleton);
 
@@ -156,14 +160,13 @@ _set_addString(USet *set, const UChar *str, int32_t length) {
  * Cleanup function for UnicodeSet
  */
 static UBool U_CALLCONV uset_cleanup(void) {
-    int32_t i;
-
-    for(i = UPROPS_SRC_NONE; i < UPROPS_SRC_COUNT; ++i) {
-        if (INCLUSIONS[i] != NULL) {
-            delete INCLUSIONS[i];
-            INCLUSIONS[i] = NULL;
-        }
+    for(int32_t i = UPROPS_SRC_NONE; i < UPROPS_SRC_COUNT; ++i) {
+        Inclusion &in = gInclusions[i];
+        delete in.fSet;
+        in.fSet = NULL;
+        in.fInitOnce.reset();
     }
+
     UnicodeSetSingleton(uni32Singleton, NULL).deleteInstance();
     return TRUE;
 }
@@ -173,105 +176,114 @@ U_CDECL_END
 U_NAMESPACE_BEGIN
 
 /*
-Reduce excessive reallocation, and make it easier to detect initialization
-problems.
+Reduce excessive reallocation, and make it easier to detect initialization problems.
 Usually you don't see smaller sets than this for Unicode 5.0.
 */
 #define DEFAULT_INCLUSION_CAPACITY 3072
 
-const UnicodeSet* UnicodeSet::getInclusions(int32_t src, UErrorCode &status) {
-    UBool needInit;
-    UMTX_CHECK(NULL, (INCLUSIONS[src] == NULL), needInit);
-    if (needInit) {
-        UnicodeSet* incl = new UnicodeSet();
-        USetAdder sa = {
-            (USet *)incl,
-            _set_add,
-            _set_addRange,
-            _set_addString,
-            NULL, // don't need remove()
-            NULL // don't need removeRange()
-        };
-        if (incl != NULL) {
-            incl->ensureCapacity(DEFAULT_INCLUSION_CAPACITY, status);
-            switch(src) {
-            case UPROPS_SRC_CHAR:
-                uchar_addPropertyStarts(&sa, &status);
-                break;
-            case UPROPS_SRC_PROPSVEC:
-                upropsvec_addPropertyStarts(&sa, &status);
-                break;
-            case UPROPS_SRC_CHAR_AND_PROPSVEC:
-                uchar_addPropertyStarts(&sa, &status);
-                upropsvec_addPropertyStarts(&sa, &status);
-                break;
+void U_CALLCONV UnicodeSet_initInclusion(int32_t src, UErrorCode &status) {
+    // This function is invoked only via umtx_initOnce().
+    // This function is a friend of class UnicodeSet.
+
+    U_ASSERT(src >=0 && src<UPROPS_SRC_COUNT);
+    UnicodeSet * &incl = gInclusions[src].fSet;
+    U_ASSERT(incl == NULL);
+
+    incl = new UnicodeSet();
+    if (incl == NULL) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    USetAdder sa = {
+        (USet *)incl,
+        _set_add,
+        _set_addRange,
+        _set_addString,
+        NULL, // don't need remove()
+        NULL // don't need removeRange()
+    };
+
+    incl->ensureCapacity(DEFAULT_INCLUSION_CAPACITY, status);
+    switch(src) {
+    case UPROPS_SRC_CHAR:
+        uchar_addPropertyStarts(&sa, &status);
+        break;
+    case UPROPS_SRC_PROPSVEC:
+        upropsvec_addPropertyStarts(&sa, &status);
+        break;
+    case UPROPS_SRC_CHAR_AND_PROPSVEC:
+        uchar_addPropertyStarts(&sa, &status);
+        upropsvec_addPropertyStarts(&sa, &status);
+        break;
 #if !UCONFIG_NO_NORMALIZATION
-            case UPROPS_SRC_CASE_AND_NORM: {
-                const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(status);
-                if(U_SUCCESS(status)) {
-                    impl->addPropertyStarts(&sa, status);
-                }
-                ucase_addPropertyStarts(ucase_getSingleton(), &sa, &status);
-                break;
-            }
-            case UPROPS_SRC_NFC: {
-                const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(status);
-                if(U_SUCCESS(status)) {
-                    impl->addPropertyStarts(&sa, status);
-                }
-                break;
-            }
-            case UPROPS_SRC_NFKC: {
-                const Normalizer2Impl *impl=Normalizer2Factory::getNFKCImpl(status);
-                if(U_SUCCESS(status)) {
-                    impl->addPropertyStarts(&sa, status);
-                }
-                break;
-            }
-            case UPROPS_SRC_NFKC_CF: {
-                const Normalizer2Impl *impl=Normalizer2Factory::getNFKC_CFImpl(status);
-                if(U_SUCCESS(status)) {
-                    impl->addPropertyStarts(&sa, status);
-                }
-                break;
-            }
-            case UPROPS_SRC_NFC_CANON_ITER: {
-                const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(status);
-                if(U_SUCCESS(status)) {
-                    impl->addCanonIterPropertyStarts(&sa, status);
-                }
-                break;
-            }
-#endif
-            case UPROPS_SRC_CASE:
-                ucase_addPropertyStarts(ucase_getSingleton(), &sa, &status);
-                break;
-            case UPROPS_SRC_BIDI:
-                ubidi_addPropertyStarts(ubidi_getSingleton(), &sa, &status);
-                break;
-            default:
-                status = U_INTERNAL_PROGRAM_ERROR;
-                break;
-            }
-            if (U_SUCCESS(status)) {
-                // Compact for caching
-                incl->compact();
-                umtx_lock(NULL);
-                if (INCLUSIONS[src] == NULL) {
-                    INCLUSIONS[src] = incl;
-                    incl = NULL;
-                    ucln_common_registerCleanup(UCLN_COMMON_USET, uset_cleanup);
-                }
-                umtx_unlock(NULL);
-            }
-            delete incl;
-        } else {
-            status = U_MEMORY_ALLOCATION_ERROR;
+    case UPROPS_SRC_CASE_AND_NORM: {
+        const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(status);
+        if(U_SUCCESS(status)) {
+            impl->addPropertyStarts(&sa, status);
+        }
+        ucase_addPropertyStarts(ucase_getSingleton(), &sa, &status);
+        break;
+    }
+    case UPROPS_SRC_NFC: {
+        const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(status);
+        if(U_SUCCESS(status)) {
+            impl->addPropertyStarts(&sa, status);
+        }
+        break;
+    }
+    case UPROPS_SRC_NFKC: {
+        const Normalizer2Impl *impl=Normalizer2Factory::getNFKCImpl(status);
+        if(U_SUCCESS(status)) {
+            impl->addPropertyStarts(&sa, status);
+        }
+        break;
+    }
+    case UPROPS_SRC_NFKC_CF: {
+        const Normalizer2Impl *impl=Normalizer2Factory::getNFKC_CFImpl(status);
+        if(U_SUCCESS(status)) {
+            impl->addPropertyStarts(&sa, status);
         }
+        break;
     }
-    return INCLUSIONS[src];
+    case UPROPS_SRC_NFC_CANON_ITER: {
+        const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(status);
+        if(U_SUCCESS(status)) {
+            impl->addCanonIterPropertyStarts(&sa, status);
+        }
+        break;
+    }
+#endif
+    case UPROPS_SRC_CASE:
+        ucase_addPropertyStarts(ucase_getSingleton(), &sa, &status);
+        break;
+    case UPROPS_SRC_BIDI:
+        ubidi_addPropertyStarts(ubidi_getSingleton(), &sa, &status);
+        break;
+    default:
+        status = U_INTERNAL_PROGRAM_ERROR;
+        break;
+    }
+
+    if (U_FAILURE(status)) {
+        delete incl;
+        incl = NULL;
+        return;
+    }
+    // Compact for caching
+    incl->compact();
+    ucln_common_registerCleanup(UCLN_COMMON_USET, uset_cleanup);
 }
 
+
+
+const UnicodeSet* UnicodeSet::getInclusions(int32_t src, UErrorCode &status) {
+    U_ASSERT(src >=0 && src<UPROPS_SRC_COUNT);
+    Inclusion &i = gInclusions[src];
+    umtx_initOnce(i.fInitOnce, &UnicodeSet_initInclusion, src, status);
+    return i.fSet;
+}
+
+
 // Cache some sets for other services -------------------------------------- ***
 
 U_CFUNC UnicodeSet *
index 52125ff28707c0cb025d53e0f75c70b4ceca44d1..f52550beca987ba7d69d0d3df93cdcb34dfbbf96 100644 (file)
@@ -1,6 +1,6 @@
 /*
 ******************************************************************************
-* Copyright (C) 1999-2012, International Business Machines Corporation and
+* Copyright (C) 1999-2013, International Business Machines Corporation and
 * others. All Rights Reserved.
 ******************************************************************************
 *
@@ -118,11 +118,11 @@ operator+ (const UnicodeString &s1, const UnicodeString &s2) {
 
 void
 UnicodeString::addRef()
-{  umtx_atomic_inc((int32_t *)fUnion.fFields.fArray - 1);}
+{  umtx_atomic_inc((atomic_int32_t *)fUnion.fFields.fArray - 1);}
 
 int32_t
 UnicodeString::removeRef()
-{ return umtx_atomic_dec((int32_t *)fUnion.fFields.fArray - 1);}
+{ return umtx_atomic_dec((atomic_int32_t *)fUnion.fFields.fArray - 1);}
 
 int32_t
 UnicodeString::refCount() const 
@@ -1679,13 +1679,16 @@ UnicodeString::cloneArrayIfNeeded(int32_t newCapacity,
       // release the old array
       if(flags & kRefCounted) {
         // the array is refCounted; decrement and release if 0
-        int32_t *pRefCount = ((int32_t *)oldArray - 1);
+        atomic_int32_t *pRefCount = ((atomic_int32_t *)oldArray - 1);
         if(umtx_atomic_dec(pRefCount) == 0) {
           if(pBufferToDelete == 0) {
-            uprv_free(pRefCount);
+              // Note: cast to (void *) is needed with MSVC, where atomic_int32_t
+              // is defined as volatile. (Volatile has useful non-standard behavior
+              //   with this compiler.)
+            uprv_free((void *)pRefCount);
           } else {
             // the caller requested to delete it himself
-            *pBufferToDelete = pRefCount;
+            *pBufferToDelete = (int32_t *)pRefCount;
           }
         }
       }
index 313fc8a1052c553100016d03e510b1ac1d2db460..5fe8820351d09feefed918bc4dcff5673813b78f 100644 (file)
@@ -34,6 +34,7 @@
 #include "ulocimp.h"
 #include "umutex.h"
 #include "putilimp.h"
+#include "uassert.h"
 
 
 /*
@@ -42,6 +43,7 @@ TODO: This cache should probably be removed when the deprecated code is
       completely removed.
 */
 static UHashtable *cache = NULL;
+static UInitOnce   gCacheInitOnce;
 
 static UMutex resbMutex = U_MUTEX_INITIALIZER;
 
@@ -261,29 +263,19 @@ static UBool U_CALLCONV ures_cleanup(void)
             cache = NULL;
         }
     }
+    gCacheInitOnce.reset();
     return (cache == NULL);
 }
 
 /** INTERNAL: Initializes the cache for resources */
+static void createCache(UErrorCode &status) {
+    U_ASSERT(cache == NULL);
+    cache = uhash_open(hashEntry, compareEntries, NULL, &status);
+    ucln_common_registerCleanup(UCLN_COMMON_URES, ures_cleanup);
+}
+     
 static void initCache(UErrorCode *status) {
-    UBool makeCache = FALSE;
-    UMTX_CHECK(&resbMutex, (cache ==  NULL), makeCache);
-    if(makeCache) {
-        UHashtable *newCache = uhash_open(hashEntry, compareEntries, NULL, status);
-        if (U_FAILURE(*status)) {
-            return;
-        }
-        umtx_lock(&resbMutex);
-        if(cache == NULL) {
-            cache = newCache;
-            newCache = NULL;
-            ucln_common_registerCleanup(UCLN_COMMON_URES, ures_cleanup);
-        }
-        umtx_unlock(&resbMutex);
-        if(newCache != NULL) {
-            uhash_close(newCache);
-        }
-    }
+    umtx_initOnce(gCacheInitOnce, &createCache, *status);
 }
 
 /** INTERNAL: sets the name (locale) of the resource bundle to given name */
index 93832e9652150ca7fb83f79a8a36f2dae796ffae..722f6b2510173efe1fcda7f7505e9edae5cc202e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *******************************************************************************
  *
- *   Copyright (C) 2003-2012, International Business Machines
+ *   Copyright (C) 2003-2013, International Business Machines
  *   Corporation and others.  All Rights Reserved.
  *
  *******************************************************************************
@@ -42,6 +42,7 @@ U_CDECL_BEGIN
 Static cache for already opened StringPrep profiles
 */
 static UHashtable *SHARED_DATA_HASHTABLE = NULL;
+static UInitOnce   gSharedDataInitOnce;
 
 static UMutex usprepMutex = U_MUTEX_INITIALIZER;
 
@@ -195,32 +196,25 @@ static UBool U_CALLCONV usprep_cleanup(void){
             SHARED_DATA_HASHTABLE = NULL;
         }
     }
-
+    gSharedDataInitOnce.reset();
     return (SHARED_DATA_HASHTABLE == NULL);
 }
 U_CDECL_END
 
 
 /** Initializes the cache for resources */
+static void U_CALLCONV
+createCache(UErrorCode &status) {
+    SHARED_DATA_HASHTABLE = uhash_open(hashEntry, compareEntries, NULL, &status);
+    if (U_FAILURE(status)) {
+        SHARED_DATA_HASHTABLE = NULL;
+    }
+    ucln_common_registerCleanup(UCLN_COMMON_USPREP, usprep_cleanup);
+}
+
 static void 
 initCache(UErrorCode *status) {
-    UBool makeCache;
-    UMTX_CHECK(&usprepMutex, (SHARED_DATA_HASHTABLE ==  NULL), makeCache);
-    if(makeCache) {
-        UHashtable *newCache = uhash_open(hashEntry, compareEntries, NULL, status);
-        if (U_SUCCESS(*status)) {
-            umtx_lock(&usprepMutex);
-            if(SHARED_DATA_HASHTABLE == NULL) {
-                SHARED_DATA_HASHTABLE = newCache;
-                ucln_common_registerCleanup(UCLN_COMMON_USPREP, usprep_cleanup);
-                newCache = NULL;
-            }
-            umtx_unlock(&usprepMutex);
-        }
-        if(newCache != NULL) {
-            uhash_close(newCache);
-        }
-    }
+    umtx_initOnce(gSharedDataInitOnce, &createCache, *status);
 }
 
 static UBool U_CALLCONV
index ac6a9256a967aa839f1f930ec825612bae3810e2..79a67f4e5e388048cfc33e136dbae07189e53c39 100644 (file)
@@ -1,7 +1,7 @@
 /*
 ******************************************************************************
 *
-*   Copyright (C) 2001-2011, International Business Machines
+*   Copyright (C) 2001-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
@@ -735,9 +735,7 @@ uint16_t ForwardUTrie2StringIterator::next16() {
 
 UTrie2 *UTrie2Singleton::getInstance(InstantiatorFn *instantiator, const void *context,
                                      UErrorCode &errorCode) {
-    void *duplicate;
-    UTrie2 *instance=(UTrie2 *)singleton.getInstance(instantiator, context, duplicate, errorCode);
-    utrie2_close((UTrie2 *)duplicate);
+    UTrie2 *instance=(UTrie2 *)singleton.getInstance(instantiator, context, errorCode);
     return instance;
 }
 
index 366f0cc7446f265a8a5cc25017ff12fcc6f68222..dcf2befed92fa3f1064a8fa11b25f8e2043b4813 100644 (file)
@@ -1,11 +1,11 @@
 ## -*-makefile-*-
 ## Linux-specific setup
-## Copyright (c) 1999-2012, International Business Machines Corporation and
+## Copyright (c) 1999-2013, International Business Machines Corporation and
 ## others. All Rights Reserved.
 
 ## Commands to generate dependency files
 GEN_DEPS.c=  $(CC) -E -MM $(DEFS) $(CPPFLAGS)
-GEN_DEPS.cc= $(CXX) -E -MM $(DEFS) $(CPPFLAGS)
+GEN_DEPS.cc= $(CXX) -E -MM $(DEFS) $(CPPFLAGS) $(CXXFLAGS)
 
 ## Flags for position independent code
 SHAREDLIBCFLAGS = -fPIC
index a27065004eb44a1cb19b10500606311676299f05..8944e2acb850a2adf27374dec3606b10754ac17b 100644 (file)
@@ -91,7 +91,7 @@
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x86\Release/icuio.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x86\Debug/icuio.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>\r
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Release/icuio.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Debug/icuio.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>\r
index 8486f996e0249a298b6f32fdcbc7fb278ee89723..ddf81679d11ceebd468bfd577411f29f7bc4350a 100644 (file)
@@ -1,7 +1,7 @@
 /*
 *******************************************************************************
 *
-*   Copyright (C) 1998-2012, International Business Machines
+*   Copyright (C) 1998-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
@@ -25,6 +25,7 @@
 #include "cmemory.h"
 #include "cstring.h"
 #include "ucln_io.h"
+#include "mutex.h"
 #include "umutex.h"
 #include "unicode/ustring.h"
 #include "unicode/uloc.h"
@@ -42,27 +43,24 @@ static UBool U_CALLCONV locbund_cleanup(void) {
 }
 U_CDECL_END
 
-
+static UMutex gLock = U_MUTEX_INITIALIZER;
 static inline UNumberFormat * copyInvariantFormatter(ULocaleBundle *result, UNumberFormatStyle style) {
+    U_NAMESPACE_USE
+    Mutex lock(&gLock);
     if (result->fNumberFormat[style-1] == NULL) {
-        UErrorCode status = U_ZERO_ERROR;
-        UBool needsInit;
-
-        UMTX_CHECK(NULL, gPosixNumberFormat[style-1] == NULL, needsInit);
-        if (needsInit) {
+        if (gPosixNumberFormat[style-1] == NULL) {
+            UErrorCode status = U_ZERO_ERROR;
             UNumberFormat *formatAlias = unum_open(style, NULL, 0, "en_US_POSIX", NULL, &status);
-
-            /* Cache upon first request. */
             if (U_SUCCESS(status)) {
-                umtx_lock(NULL);
                 gPosixNumberFormat[style-1] = formatAlias;
                 ucln_io_registerCleanup(UCLN_IO_LOCBUND, locbund_cleanup);
-                umtx_unlock(NULL);
             }
         }
-
         /* Copy the needed formatter. */
-        result->fNumberFormat[style-1] = unum_clone(gPosixNumberFormat[style-1], &status);
+        if (gPosixNumberFormat[style-1] != NULL) {
+            UErrorCode status = U_ZERO_ERROR;
+            result->fNumberFormat[style-1] = unum_clone(gPosixNumberFormat[style-1], &status);
+        }
     }
     return result->fNumberFormat[style-1];
 }
index b7e39c9a5a61e38d1c4fbfb50cd9d8bb452a7e70..13dae70bfa82668cff8870af64366939f8744db1 100644 (file)
-<?xml version="1.0" encoding="utf-8"?>\r
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
-  <ItemGroup Label="ProjectConfigurations">\r
-    <ProjectConfiguration Include="Debug|Win32">\r
-      <Configuration>Debug</Configuration>\r
-      <Platform>Win32</Platform>\r
-    </ProjectConfiguration>\r
-    <ProjectConfiguration Include="Debug|x64">\r
-      <Configuration>Debug</Configuration>\r
-      <Platform>x64</Platform>\r
-    </ProjectConfiguration>\r
-    <ProjectConfiguration Include="Release|Win32">\r
-      <Configuration>Release</Configuration>\r
-      <Platform>Win32</Platform>\r
-    </ProjectConfiguration>\r
-    <ProjectConfiguration Include="Release|x64">\r
-      <Configuration>Release</Configuration>\r
-      <Platform>x64</Platform>\r
-    </ProjectConfiguration>\r
-  </ItemGroup>\r
-  <PropertyGroup Label="Globals">\r
-    <ProjectGuid>{F7659D77-09CF-4FE9-ACEE-927287AA9509}</ProjectGuid>\r
-  </PropertyGroup>\r
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
-    <ConfigurationType>Application</ConfigurationType>\r
-    <UseOfMfc>false</UseOfMfc>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
-  </PropertyGroup>\r
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
-    <ConfigurationType>Application</ConfigurationType>\r
-    <UseOfMfc>false</UseOfMfc>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
-  </PropertyGroup>\r
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
-    <ConfigurationType>Application</ConfigurationType>\r
-    <UseOfMfc>false</UseOfMfc>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
-  </PropertyGroup>\r
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
-    <ConfigurationType>Application</ConfigurationType>\r
-    <UseOfMfc>false</UseOfMfc>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
-  </PropertyGroup>\r
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
-  <ImportGroup Label="ExtensionSettings">\r
-  </ImportGroup>\r
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
-    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />\r
-  </ImportGroup>\r
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
-    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />\r
-  </ImportGroup>\r
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">\r
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
-    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />\r
-  </ImportGroup>\r
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">\r
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
-    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />\r
-  </ImportGroup>\r
-  <PropertyGroup Label="UserMacros" />\r
-  <PropertyGroup>\r
-    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\x86\Release\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\x86\Release\</IntDir>\r
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</IntDir>\r
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\x86\Debug\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\x86\Debug\</IntDir>\r
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>\r
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\x64\Debug\</OutDir>\r
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\x64\Debug\</IntDir>\r
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>\r
-  </PropertyGroup>\r
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
-    <Midl>\r
-      <TypeLibraryName>.\x86\Release/cal.tlb</TypeLibraryName>\r
-    </Midl>\r
-    <ClCompile>\r
-      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
-      <AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
-      <StringPooling>true</StringPooling>\r
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
-      <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
-      <PrecompiledHeaderOutputFile>.\x86\Release/cal.pch</PrecompiledHeaderOutputFile>\r
-      <AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>\r
-      <ObjectFileName>.\x86\Release/</ObjectFileName>\r
-      <ProgramDataBaseFileName>.\x86\Release/</ProgramDataBaseFileName>\r
-      <WarningLevel>Level3</WarningLevel>\r
-      <SuppressStartupBanner>true</SuppressStartupBanner>\r
-      <CompileAs>Default</CompileAs>\r
-    </ClCompile>\r
-    <ResourceCompile>\r
-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
-      <Culture>0x0409</Culture>\r
-    </ResourceCompile>\r
-    <Link>\r
-      <AdditionalDependencies>icuuc.lib;icuin.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
-      <OutputFile>.\x86\Release/cal.exe</OutputFile>\r
-      <SuppressStartupBanner>true</SuppressStartupBanner>\r
-      <AdditionalLibraryDirectories>../../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
-      <ProgramDatabaseFile>.\x86\Release/cal.pdb</ProgramDatabaseFile>\r
-      <SubSystem>Console</SubSystem>\r
-      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
-      <DataExecutionPrevention>\r
-      </DataExecutionPrevention>\r
-    </Link>\r
-  </ItemDefinitionGroup>\r
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
-    <Midl>\r
-      <TargetEnvironment>X64</TargetEnvironment>\r
-      <TypeLibraryName>.\x64\Release/cal.tlb</TypeLibraryName>\r
-    </Midl>\r
-    <ClCompile>\r
-      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
-      <AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>WIN64;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
-      <StringPooling>true</StringPooling>\r
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
-      <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
-      <PrecompiledHeaderOutputFile>.\x64\Release/cal.pch</PrecompiledHeaderOutputFile>\r
-      <AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>\r
-      <ObjectFileName>.\x64\Release/</ObjectFileName>\r
-      <ProgramDataBaseFileName>.\x64\Release/</ProgramDataBaseFileName>\r
-      <WarningLevel>Level3</WarningLevel>\r
-      <SuppressStartupBanner>true</SuppressStartupBanner>\r
-      <CompileAs>Default</CompileAs>\r
-    </ClCompile>\r
-    <ResourceCompile>\r
-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
-      <Culture>0x0409</Culture>\r
-    </ResourceCompile>\r
-    <Link>\r
-      <AdditionalDependencies>icuuc.lib;icuin.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
-      <OutputFile>.\x64\Release/cal.exe</OutputFile>\r
-      <SuppressStartupBanner>true</SuppressStartupBanner>\r
-      <AdditionalLibraryDirectories>../../../lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
-      <ProgramDatabaseFile>.\x64\Release/cal.pdb</ProgramDatabaseFile>\r
-      <SubSystem>Console</SubSystem>\r
-      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
-      <DataExecutionPrevention>\r
-      </DataExecutionPrevention>\r
-      <TargetMachine>MachineX64</TargetMachine>\r
-    </Link>\r
-  </ItemDefinitionGroup>\r
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
-    <Midl>\r
-      <TypeLibraryName>.\x86\Debug/cal.tlb</TypeLibraryName>\r
-    </Midl>\r
-    <ClCompile>\r
-      <Optimization>Disabled</Optimization>\r
-      <AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
-      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
-      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
-      <PrecompiledHeaderOutputFile>.\x86\Debug/cal.pch</PrecompiledHeaderOutputFile>\r
-      <AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>\r
-      <ObjectFileName>.\x86\Debug/</ObjectFileName>\r
-      <ProgramDataBaseFileName>.\x86\Debug/</ProgramDataBaseFileName>\r
-      <BrowseInformation>true</BrowseInformation>\r
-      <WarningLevel>Level3</WarningLevel>\r
-      <SuppressStartupBanner>true</SuppressStartupBanner>\r
-      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\r
-      <CompileAs>Default</CompileAs>\r
-    </ClCompile>\r
-    <ResourceCompile>\r
-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
-      <Culture>0x0409</Culture>\r
-    </ResourceCompile>\r
-    <Link>\r
-      <AdditionalDependencies>icuucd.lib;icuind.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
-      <OutputFile>.\x86\Debug/cal.exe</OutputFile>\r
-      <SuppressStartupBanner>true</SuppressStartupBanner>\r
-      <AdditionalLibraryDirectories>../../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
-      <GenerateDebugInformation>true</GenerateDebugInformation>\r
-      <ProgramDatabaseFile>.\x86\Debug/cal.pdb</ProgramDatabaseFile>\r
-      <SubSystem>Console</SubSystem>\r
-      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
-      <DataExecutionPrevention>\r
-      </DataExecutionPrevention>\r
-    </Link>\r
-  </ItemDefinitionGroup>\r
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
-    <Midl>\r
-      <TargetEnvironment>X64</TargetEnvironment>\r
-      <TypeLibraryName>.\x64\Debug/cal.tlb</TypeLibraryName>\r
-    </Midl>\r
-    <ClCompile>\r
-      <Optimization>Disabled</Optimization>\r
-      <AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>WIN64;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
-      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
-      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
-      <PrecompiledHeader>\r
-      </PrecompiledHeader>\r
-      <PrecompiledHeaderOutputFile>.\x64\Debug/cal.pch</PrecompiledHeaderOutputFile>\r
-      <AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>\r
-      <ObjectFileName>.\x64\Debug/</ObjectFileName>\r
-      <ProgramDataBaseFileName>.\x64\Debug/</ProgramDataBaseFileName>\r
-      <BrowseInformation>true</BrowseInformation>\r
-      <WarningLevel>Level3</WarningLevel>\r
-      <SuppressStartupBanner>true</SuppressStartupBanner>\r
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
-      <CompileAs>Default</CompileAs>\r
-    </ClCompile>\r
-    <ResourceCompile>\r
-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
-      <Culture>0x0409</Culture>\r
-    </ResourceCompile>\r
-    <Link>\r
-      <AdditionalDependencies>icuucd.lib;icuind.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
-      <OutputFile>.\x64\Debug/cal.exe</OutputFile>\r
-      <SuppressStartupBanner>true</SuppressStartupBanner>\r
-      <AdditionalLibraryDirectories>../../../lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
-      <GenerateDebugInformation>true</GenerateDebugInformation>\r
-      <ProgramDatabaseFile>.\x64\Debug/cal.pdb</ProgramDatabaseFile>\r
-      <SubSystem>Console</SubSystem>\r
-      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
-      <DataExecutionPrevention>\r
-      </DataExecutionPrevention>\r
-      <TargetMachine>MachineX64</TargetMachine>\r
-    </Link>\r
-  </ItemDefinitionGroup>\r
-  <ItemGroup>\r
-    <ClCompile Include="cal.c" />\r
-    <ClCompile Include="uprint.c" />\r
-  </ItemGroup>\r
-  <ItemGroup>\r
-    <ClInclude Include="uprint.h" />\r
-  </ItemGroup>\r
-  <ItemGroup>\r
-    <ProjectReference Include="..\..\common\common.vcxproj">\r
-      <Project>{73c0a65b-d1f2-4de1-b3a6-15dad2c23f3d}</Project>\r
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
-    </ProjectReference>\r
-    <ProjectReference Include="..\..\i18n\i18n.vcxproj">\r
-      <Project>{0178b127-6269-407d-b112-93877bb62776}</Project>\r
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
-    </ProjectReference>\r
-  </ItemGroup>\r
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
-  <ImportGroup Label="ExtensionTargets">\r
-  </ImportGroup>\r
-</Project>
+<?xml version="1.0" encoding="utf-8"?>\r\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r\r
+  <ItemGroup Label="ProjectConfigurations">\r\r
+    <ProjectConfiguration Include="Debug|Win32">\r\r
+      <Configuration>Debug</Configuration>\r\r
+      <Platform>Win32</Platform>\r\r
+    </ProjectConfiguration>\r\r
+    <ProjectConfiguration Include="Debug|x64">\r\r
+      <Configuration>Debug</Configuration>\r\r
+      <Platform>x64</Platform>\r\r
+    </ProjectConfiguration>\r\r
+    <ProjectConfiguration Include="Release|Win32">\r\r
+      <Configuration>Release</Configuration>\r\r
+      <Platform>Win32</Platform>\r\r
+    </ProjectConfiguration>\r\r
+    <ProjectConfiguration Include="Release|x64">\r\r
+      <Configuration>Release</Configuration>\r\r
+      <Platform>x64</Platform>\r\r
+    </ProjectConfiguration>\r\r
+  </ItemGroup>\r\r
+  <PropertyGroup Label="Globals">\r\r
+    <ProjectGuid>{F7659D77-09CF-4FE9-ACEE-927287AA9509}</ProjectGuid>\r\r
+  </PropertyGroup>\r\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r\r
+    <ConfigurationType>Application</ConfigurationType>\r\r
+    <UseOfMfc>false</UseOfMfc>\r\r
+    <CharacterSet>MultiByte</CharacterSet>\r\r
+  </PropertyGroup>\r\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r\r
+    <ConfigurationType>Application</ConfigurationType>\r\r
+    <UseOfMfc>false</UseOfMfc>\r\r
+    <CharacterSet>MultiByte</CharacterSet>\r\r
+  </PropertyGroup>\r\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r\r
+    <ConfigurationType>Application</ConfigurationType>\r\r
+    <UseOfMfc>false</UseOfMfc>\r\r
+    <CharacterSet>MultiByte</CharacterSet>\r\r
+  </PropertyGroup>\r\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r\r
+    <ConfigurationType>Application</ConfigurationType>\r\r
+    <UseOfMfc>false</UseOfMfc>\r\r
+    <CharacterSet>MultiByte</CharacterSet>\r\r
+  </PropertyGroup>\r\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r\r
+  <ImportGroup Label="ExtensionSettings">\r\r
+  </ImportGroup>\r\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r\r
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />\r\r
+  </ImportGroup>\r\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r\r
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />\r\r
+  </ImportGroup>\r\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">\r\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r\r
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />\r\r
+  </ImportGroup>\r\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">\r\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r\r
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />\r\r
+  </ImportGroup>\r\r
+  <PropertyGroup Label="UserMacros" />\r\r
+  <PropertyGroup>\r\r
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\x86\Release\</OutDir>\r\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\x86\Release\</IntDir>\r\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</OutDir>\r\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</IntDir>\r\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\x86\Debug\</OutDir>\r\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\x86\Debug\</IntDir>\r\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>\r\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\x64\Debug\</OutDir>\r\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\x64\Debug\</IntDir>\r\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>\r\r
+  </PropertyGroup>\r\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r\r
+    <Midl>\r\r
+      <TypeLibraryName>.\x86\Release/cal.tlb</TypeLibraryName>\r\r
+    </Midl>\r\r
+    <ClCompile>\r\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r\r
+      <AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\r
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\r
+      <StringPooling>true</StringPooling>\r\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r\r
+      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r\r
+      <PrecompiledHeader>\r\r
+      </PrecompiledHeader>\r\r
+      <PrecompiledHeaderOutputFile>.\x86\Release/cal.pch</PrecompiledHeaderOutputFile>\r\r
+      <AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>\r\r
+      <ObjectFileName>.\x86\Release/</ObjectFileName>\r\r
+      <ProgramDataBaseFileName>.\x86\Release/</ProgramDataBaseFileName>\r\r
+      <WarningLevel>Level3</WarningLevel>\r\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r\r
+      <CompileAs>Default</CompileAs>\r\r
+    </ClCompile>\r\r
+    <ResourceCompile>\r\r
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\r
+      <Culture>0x0409</Culture>\r\r
+    </ResourceCompile>\r\r
+    <Link>\r\r
+      <AdditionalDependencies>icuuc.lib;icuin.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\r
+      <OutputFile>.\x86\Release/cal.exe</OutputFile>\r\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r\r
+      <AdditionalLibraryDirectories>../../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r\r
+      <ProgramDatabaseFile>.\x86\Release/cal.pdb</ProgramDatabaseFile>\r\r
+      <SubSystem>Console</SubSystem>\r\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r\r
+      <DataExecutionPrevention>\r\r
+      </DataExecutionPrevention>\r\r
+    </Link>\r\r
+  </ItemDefinitionGroup>\r\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r\r
+    <Midl>\r\r
+      <TargetEnvironment>X64</TargetEnvironment>\r\r
+      <TypeLibraryName>.\x64\Release/cal.tlb</TypeLibraryName>\r\r
+    </Midl>\r\r
+    <ClCompile>\r\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r\r
+      <AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\r
+      <PreprocessorDefinitions>WIN64;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\r
+      <StringPooling>true</StringPooling>\r\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r\r
+      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r\r
+      <PrecompiledHeader>\r\r
+      </PrecompiledHeader>\r\r
+      <PrecompiledHeaderOutputFile>.\x64\Release/cal.pch</PrecompiledHeaderOutputFile>\r\r
+      <AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>\r\r
+      <ObjectFileName>.\x64\Release/</ObjectFileName>\r\r
+      <ProgramDataBaseFileName>.\x64\Release/</ProgramDataBaseFileName>\r\r
+      <WarningLevel>Level3</WarningLevel>\r\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r\r
+      <CompileAs>Default</CompileAs>\r\r
+    </ClCompile>\r\r
+    <ResourceCompile>\r\r
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\r
+      <Culture>0x0409</Culture>\r\r
+    </ResourceCompile>\r\r
+    <Link>\r\r
+      <AdditionalDependencies>icuuc.lib;icuin.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\r
+      <OutputFile>.\x64\Release/cal.exe</OutputFile>\r\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r\r
+      <AdditionalLibraryDirectories>../../../lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r\r
+      <ProgramDatabaseFile>.\x64\Release/cal.pdb</ProgramDatabaseFile>\r\r
+      <SubSystem>Console</SubSystem>\r\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r\r
+      <DataExecutionPrevention>\r\r
+      </DataExecutionPrevention>\r\r
+      <TargetMachine>MachineX64</TargetMachine>\r\r
+    </Link>\r\r
+  </ItemDefinitionGroup>\r\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r\r
+    <Midl>\r\r
+      <TypeLibraryName>.\x86\Debug/cal.tlb</TypeLibraryName>\r\r
+    </Midl>\r\r
+    <ClCompile>\r\r
+      <Optimization>Disabled</Optimization>\r\r
+      <AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\r
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\r
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r\r
+      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r\r
+      <PrecompiledHeader>\r\r
+      </PrecompiledHeader>\r\r
+      <PrecompiledHeaderOutputFile>.\x86\Debug/cal.pch</PrecompiledHeaderOutputFile>\r\r
+      <AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>\r\r
+      <ObjectFileName>.\x86\Debug/</ObjectFileName>\r\r
+      <ProgramDataBaseFileName>.\x86\Debug/</ProgramDataBaseFileName>\r\r
+      <BrowseInformation>true</BrowseInformation>\r\r
+      <WarningLevel>Level3</WarningLevel>\r\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r\r
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\r\r
+      <CompileAs>Default</CompileAs>\r\r
+    </ClCompile>\r\r
+    <ResourceCompile>\r\r
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\r
+      <Culture>0x0409</Culture>\r\r
+    </ResourceCompile>\r\r
+    <Link>\r\r
+      <AdditionalDependencies>icuucd.lib;icuind.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\r
+      <OutputFile>.\x86\Debug/cal.exe</OutputFile>\r\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r\r
+      <AdditionalLibraryDirectories>../../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r\r
+      <ProgramDatabaseFile>.\x86\Debug/cal.pdb</ProgramDatabaseFile>\r\r
+      <SubSystem>Console</SubSystem>\r\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r\r
+      <DataExecutionPrevention>\r\r
+      </DataExecutionPrevention>\r\r
+    </Link>\r\r
+  </ItemDefinitionGroup>\r\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r\r
+    <Midl>\r\r
+      <TargetEnvironment>X64</TargetEnvironment>\r\r
+      <TypeLibraryName>.\x64\Debug/cal.tlb</TypeLibraryName>\r\r
+    </Midl>\r\r
+    <ClCompile>\r\r
+      <Optimization>Disabled</Optimization>\r\r
+      <AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\r
+      <PreprocessorDefinitions>WIN64;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\r
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r\r
+      <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r\r
+      <PrecompiledHeader>\r\r
+      </PrecompiledHeader>\r\r
+      <PrecompiledHeaderOutputFile>.\x64\Debug/cal.pch</PrecompiledHeaderOutputFile>\r\r
+      <AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>\r\r
+      <ObjectFileName>.\x64\Debug/</ObjectFileName>\r\r
+      <ProgramDataBaseFileName>.\x64\Debug/</ProgramDataBaseFileName>\r\r
+      <BrowseInformation>true</BrowseInformation>\r\r
+      <WarningLevel>Level3</WarningLevel>\r\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r\r
+      <CompileAs>Default</CompileAs>\r\r
+    </ClCompile>\r\r
+    <ResourceCompile>\r\r
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\r
+      <Culture>0x0409</Culture>\r\r
+    </ResourceCompile>\r\r
+    <Link>\r\r
+      <AdditionalDependencies>icuucd.lib;icuind.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\r
+      <OutputFile>.\x64\Debug/cal.exe</OutputFile>\r\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r\r
+      <AdditionalLibraryDirectories>../../../lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r\r
+      <ProgramDatabaseFile>.\x64\Debug/cal.pdb</ProgramDatabaseFile>\r\r
+      <SubSystem>Console</SubSystem>\r\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r\r
+      <DataExecutionPrevention>\r\r
+      </DataExecutionPrevention>\r\r
+      <TargetMachine>MachineX64</TargetMachine>\r\r
+    </Link>\r\r
+  </ItemDefinitionGroup>\r\r
+  <ItemGroup>\r\r
+    <ClCompile Include="cal.c">\r
+           <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+    </ClCompile>\r\r
+    <ClCompile Include="uprint.c">\r
+           <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+    </ClCompile>\r\r
+  </ItemGroup>\r\r
+  <ItemGroup>\r\r
+    <ClInclude Include="uprint.h" />\r\r
+  </ItemGroup>\r\r
+  <ItemGroup>\r\r
+    <ProjectReference Include="..\..\common\common.vcxproj">\r\r
+      <Project>{73c0a65b-d1f2-4de1-b3a6-15dad2c23f3d}</Project>\r\r
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r\r
+    </ProjectReference>\r\r
+    <ProjectReference Include="..\..\i18n\i18n.vcxproj">\r\r
+      <Project>{0178b127-6269-407d-b112-93877bb62776}</Project>\r\r
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r\r
+    </ProjectReference>\r\r
+  </ItemGroup>\r\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r\r
+  <ImportGroup Label="ExtensionTargets">\r\r
+  </ImportGroup>\r\r
+</Project>\r
index 4d946dfe03f13d4ebb41f2618abcd2de56457412..ecb655e7984c0c913fb86c6787206ba7d80ab5dc 100644 (file)
@@ -1,6 +1,6 @@
 /********************************************************************
  * COPYRIGHT:
- * Copyright (c) 1997-2012, International Business Machines Corporation and
+ * Copyright (c) 1997-2013, International Business Machines Corporation and
  * others. All Rights Reserved.
  ********************************************************************/
 /********************************************************************************
@@ -234,10 +234,6 @@ int main(int argc, const char* const argv[])
 
     }  /* End of loop that repeats the entire test, if requested.  (Normally doesn't loop)  */
 
-    if (ALLOCATION_COUNT > 0) {
-        fprintf(stderr, "There were %d blocks leaked!\n", ALLOCATION_COUNT);
-        nerrors++;
-    }
     endTime = uprv_getRawUTCtime();
     diffTime = (int32_t)(endTime - startTime);
     printf("Elapsed Time: %02d:%02d:%02d.%03d\n",
index b372246e458724033ab1f8ddcfbc9c3033217d52..b53641122770cff262f299947db22d24ea1854a7 100644 (file)
@@ -88,7 +88,7 @@
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x86\Debug/cintltst.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>\r
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x86\Release/cintltst.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Debug/cintltst.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>\r
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Release/cintltst.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>\r
     <ClCompile Include="ucnvseltst.c" />\r
     <ClCompile Include="ucsdetst.c" />\r
     <ClCompile Include="udatatst.c">\r
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>\r
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>\r
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>\r
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>\r
     </ClCompile>\r
     <ClCompile Include="ccaltst.c" />\r
     <ClCompile Include="cdateintervalformattest.c" />\r
index 57ab08cc231d93c2d9a1ce35372c0c4ed4a61bb0..154c7a69f2fbf3e9ca485a1f592302c22c8a2e2f 100644 (file)
@@ -1,6 +1,6 @@
 /********************************************************************
  * COPYRIGHT: 
- * Copyright (c) 2003-2009, International Business Machines Corporation and
+ * Copyright (c) 2003-2013, International Business Machines Corporation and
  * others. All Rights Reserved.
  ********************************************************************/
 /*
@@ -29,8 +29,6 @@ typedef union {
 } ctest_AlignedMemory;
 
 static void TestHeapFunctions(void);
-static void TestMutexFunctions(void);
-static void TestIncDecFunctions(void);
 
 void addHeapMutexTest(TestNode **root);
 
@@ -39,8 +37,6 @@ void
 addHeapMutexTest(TestNode** root)
 {
     addTest(root, &TestHeapFunctions,       "hpmufn/TestHeapFunctions"  );
-    addTest(root, &TestMutexFunctions,      "hpmufn/TestMutexFunctions" );
-    addTest(root, &TestIncDecFunctions,     "hpmufn/TestIncDecFunctions");
 }
 
 static int32_t gMutexFailures = 0;
@@ -203,273 +199,3 @@ static void TestHeapFunctions() {
 }
 
 
-/*
- *  Test u_setMutexFunctions()
- */
-
-int         gTotalMutexesInitialized = 0;         /* Total number of mutexes created */
-int         gTotalMutexesActive      = 0;         /* Total mutexes created, but not destroyed  */
-int         gAccumulatedLocks        = 0;
-const void *gMutexContext;
-
-typedef struct DummyMutex {
-    int  fLockCount;
-    int  fMagic;
-} DummyMutex;
-
-
-static void U_CALLCONV myMutexInit(const void *context, UMTX *mutex, UErrorCode *status) {
-    DummyMutex *theMutex;
-
-    TEST_STATUS(*status, U_ZERO_ERROR);
-    theMutex = (DummyMutex *)malloc(sizeof(DummyMutex));
-    theMutex->fLockCount = 0;
-    theMutex->fMagic     = 123456;
-    gTotalMutexesInitialized++;
-    gTotalMutexesActive++;
-    gMutexContext = context;
-    *mutex = theMutex;
-}
-
-
-static void U_CALLCONV myMutexDestroy(const void *context, UMTX  *mutex) {
-    DummyMutex *This = *(DummyMutex **)mutex;
-
-    gTotalMutexesActive--;
-    TEST_ASSERT(This->fLockCount == 0);
-    TEST_ASSERT(This->fMagic == 123456);
-    This->fMagic = 0;
-    This->fLockCount = 0;
-    free(This);
-}
-
-static void U_CALLCONV myMutexLock(const void *context, UMTX *mutex) {
-    DummyMutex *This = *(DummyMutex **)mutex;
-
-    TEST_ASSERT(This->fMagic == 123456);
-    This->fLockCount++;
-    gAccumulatedLocks++;
-}
-
-static void U_CALLCONV myMutexUnlock(const void *context, UMTX *mutex) {
-    DummyMutex *This = *(DummyMutex **)mutex;
-
-    TEST_ASSERT(This->fMagic == 123456);
-    This->fLockCount--;
-    TEST_ASSERT(This->fLockCount >= 0);
-}
-
-
-
-static void TestMutexFunctions() {
-    UErrorCode       status = U_ZERO_ERROR;
-    UResourceBundle *rb     = NULL;
-    char            *icuDataDir;
-
-    gMutexFailures = 0;
-
-    /*  Save initial ICU state so that it can be restored later.
-     *  u_cleanup(), which is called in this test, resets ICU's state.
-     */
-    icuDataDir = safeGetICUDataDirectory();
-
-    /* Verify that ICU can be cleaned up and reinitialized successfully.
-     *  Failure here usually means that some ICU service didn't clean up successfully,
-     *  probably because some earlier test accidently left something open. */
-    ctest_resetICU();
-
-    /* Can not set mutex functions if ICU is already initialized */
-    u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, myMutexUnlock, &status);
-    TEST_STATUS(status, U_INVALID_STATE_ERROR);
-
-    /* Un-initialize ICU */
-    u_cleanup();
-
-    /* Can not set Mutex functions with NULL values */
-    status = U_ZERO_ERROR;
-    u_setMutexFunctions(&gContext, NULL, myMutexDestroy, myMutexLock, myMutexUnlock, &status);
-    TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
-    status = U_ZERO_ERROR;
-    u_setMutexFunctions(&gContext, myMutexInit, NULL, myMutexLock, myMutexUnlock, &status);
-    TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
-    status = U_ZERO_ERROR;
-    u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, NULL, myMutexUnlock, &status);
-    TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
-    status = U_ZERO_ERROR;
-    u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, NULL, &status);
-    TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
-
-    /* u_setMutexFunctions() should work with null or non-null context pointer */
-    status = U_ZERO_ERROR;
-    u_setMutexFunctions(NULL, myMutexInit, myMutexDestroy, myMutexLock, myMutexUnlock, &status);
-    TEST_STATUS(status, U_ZERO_ERROR);
-    u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, myMutexUnlock, &status);
-    TEST_STATUS(status, U_ZERO_ERROR);
-
-
-    /* After reinitializing ICU, we should not be able to set the mutex funcs again. */
-    status = U_ZERO_ERROR;
-    u_setDataDirectory(icuDataDir);
-    u_init(&status);
-    TEST_STATUS(status, U_ZERO_ERROR);
-    u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, myMutexUnlock, &status);
-    TEST_STATUS(status, U_INVALID_STATE_ERROR);
-
-    /* Doing ICU operations should cause allocations to come through our test mutexes */
-    gBlockCount = 0;
-    status = U_ZERO_ERROR;
-    /*
-     * Note: If we get assertion failures here because
-     * uresbund.c:resbMutex's fMagic is wrong, check if ures_flushCache() did
-     * flush and delete the cache. If it fails to empty the cache, it will not
-     * delete it and ures_cleanup() will not destroy resbMutex.
-     * That would leave a mutex from the default implementation which does not
-     * pass this test implementation's assertions.
-     */
-    rb = ures_open(NULL, "es", &status);
-    TEST_STATUS(status, U_ZERO_ERROR);
-    TEST_ASSERT(gTotalMutexesInitialized > 0);
-    TEST_ASSERT(gTotalMutexesActive > 0);
-
-    ures_close(rb);
-
-    /* Cleanup should destroy all of the mutexes. */
-    ctest_resetICU();
-    status = U_ZERO_ERROR;
-    TEST_ASSERT(gTotalMutexesInitialized > 0);
-    TEST_ASSERT(gTotalMutexesActive == 0);
-
-
-    /* Additional ICU operations should no longer use our dummy test mutexes */
-    gTotalMutexesInitialized = 0;
-    gTotalMutexesActive      = 0;
-    u_init(&status);
-    TEST_STATUS(status, U_ZERO_ERROR);
-
-    status = U_ZERO_ERROR;
-    rb = ures_open(NULL, "fr", &status);
-    TEST_STATUS(status, U_ZERO_ERROR);
-    TEST_ASSERT(gTotalMutexesInitialized == 0);
-    TEST_ASSERT(gTotalMutexesActive == 0);
-
-    ures_close(rb);
-    free(icuDataDir);
-
-    if(gMutexFailures) {
-      log_info("Note: these failures may be caused by ICU failing to initialize/uninitialize properly.\n");
-      log_verbose("Check for prior tests which may not have closed all open resources. See the internal function ures_flushCache()\n");
-    }
-}
-
-
-
-
-/*
- *  Test Atomic Increment & Decrement Functions
- */
-
-int         gIncCount             = 0;
-int         gDecCount             = 0;
-const void *gIncDecContext;
-const void *gExpectedContext = &gIncDecContext;
-
-
-static int32_t U_CALLCONV myIncFunc(const void *context, int32_t *p) {
-    int32_t  retVal;
-    TEST_ASSERT(context == gExpectedContext);
-    gIncCount++;
-    retVal = ++(*p);
-    return retVal;
-}
-
-static int32_t U_CALLCONV myDecFunc(const void *context, int32_t *p) {
-    int32_t  retVal;
-    TEST_ASSERT(context == gExpectedContext);
-    gDecCount++;
-    retVal = --(*p);
-    return retVal;
-}
-
-
-
-
-static void TestIncDecFunctions() {
-    UErrorCode   status = U_ZERO_ERROR;
-    int32_t      t = 1; /* random value to make sure that Inc/dec works */
-    char         *dataDir;
-
-    /* Save ICU's data dir and tracing functions so that they can be resored 
-       after cleanup and reinit.  */
-    dataDir = safeGetICUDataDirectory();
-
-    /* Verify that ICU can be cleaned up and reinitialized successfully.
-     *  Failure here usually means that some ICU service didn't clean up successfully,
-     *  probably because some earlier test accidently left something open. */
-    ctest_resetICU();
-
-    /* Can not set mutex functions if ICU is already initialized */
-    u_setAtomicIncDecFunctions(&gIncDecContext, myIncFunc, myDecFunc,  &status);
-    TEST_STATUS(status, U_INVALID_STATE_ERROR);
-
-    /* Clean up ICU */
-    u_cleanup();
-
-    /* Can not set functions with NULL values */
-    status = U_ZERO_ERROR;
-    u_setAtomicIncDecFunctions(&gIncDecContext, NULL, myDecFunc,  &status);
-    TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
-    status = U_ZERO_ERROR;
-    u_setAtomicIncDecFunctions(&gIncDecContext, myIncFunc, NULL,  &status);
-    TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
-
-    /* u_setIncDecFunctions() should work with null or non-null context pointer */
-    status = U_ZERO_ERROR;
-    gExpectedContext = NULL;
-    u_setAtomicIncDecFunctions(NULL, myIncFunc, myDecFunc,  &status);
-    TEST_STATUS(status, U_ZERO_ERROR);
-    gExpectedContext = &gIncDecContext;
-    u_setAtomicIncDecFunctions(&gIncDecContext, myIncFunc, myDecFunc,  &status);
-    TEST_STATUS(status, U_ZERO_ERROR);
-
-
-    /* After reinitializing ICU, we should not be able to set the inc/dec funcs again. */
-    status = U_ZERO_ERROR;
-    u_setDataDirectory(dataDir);
-    u_init(&status);
-    TEST_STATUS(status, U_ZERO_ERROR);
-    gExpectedContext = &gIncDecContext;
-    u_setAtomicIncDecFunctions(&gIncDecContext, myIncFunc, myDecFunc,  &status);
-    TEST_STATUS(status, U_INVALID_STATE_ERROR);
-
-    /* Doing ICU operations should cause our functions to be called */
-    gIncCount = 0;
-    gDecCount = 0;
-    umtx_atomic_inc(&t);
-    TEST_ASSERT(t == 2);
-    umtx_atomic_dec(&t);
-    TEST_ASSERT(t == 1);
-    TEST_ASSERT(gIncCount > 0);
-    TEST_ASSERT(gDecCount > 0);
-
-
-    /* Cleanup should cancel use of our inc/dec functions. */
-    /* Additional ICU operations should not use them */
-    ctest_resetICU();
-    gIncCount = 0;
-    gDecCount = 0;
-    status = U_ZERO_ERROR;
-    u_setDataDirectory(dataDir);
-    u_init(&status);
-    TEST_ASSERT(gIncCount == 0);
-    TEST_ASSERT(gDecCount == 0);
-
-    status = U_ZERO_ERROR;
-    umtx_atomic_inc(&t);
-    umtx_atomic_dec(&t);
-    TEST_STATUS(status, U_ZERO_ERROR);
-    TEST_ASSERT(gIncCount == 0);
-    TEST_ASSERT(gDecCount == 0);
-
-    free(dataDir);
-}
-
index 3bb847068053e253bb9016651821b57412f92c6d..8a6698ed97047f0ca0a77a997eae6695d9ca8e95 100644 (file)
     <ClCompile Include="regiontst.cpp" />\r
     <ClCompile Include="ucharstrietest.cpp" />\r
     <ClCompile Include="itrbbi.cpp" />\r
-    <ClCompile Include="rbbiapts.cpp" />\r
+    <ClCompile Include="rbbiapts.cpp">\r
+        <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+    </ClCompile>\r
     <ClCompile Include="rbbitst.cpp" />\r
     <ClCompile Include="itspoof.cpp" />\r
     <ClCompile Include="allcoll.cpp" />\r
     <ClCompile Include="uvectest.cpp" />\r
     <ClCompile Include="v32test.cpp" />\r
     <ClCompile Include="simplethread.cpp">\r
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>\r
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>\r
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>\r
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>\r
+           <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
     </ClCompile>\r
     <ClCompile Include="strtest.cpp">\r
       <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>\r
       <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>\r
     </ClCompile>\r
     <ClCompile Include="tsputil.cpp" />\r
-    <ClCompile Include="uobjtest.cpp" />\r
+    <ClCompile Include="uobjtest.cpp">\r
+           <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+    </ClCompile>\r
     <ClCompile Include="astrotst.cpp" />\r
     <ClCompile Include="calcasts.cpp" />\r
     <ClCompile Include="callimts.cpp" />\r
     <ClCompile Include="calregts.cpp" />\r
     <ClCompile Include="caltest.cpp" />\r
-    <ClCompile Include="caltztst.cpp" />\r
+    <ClCompile Include="caltztst.cpp">\r
+           <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+    </ClCompile>\r
     <ClCompile Include="compactdecimalformattest.cpp" />\r
     <ClCompile Include="dadrcal.cpp" />\r
     <ClCompile Include="dadrfmt.cpp" />\r
     <ClCompile Include="tsnmfmt.cpp" />\r
     <ClCompile Include="tufmtts.cpp" />\r
     <ClCompile Include="tzbdtest.cpp" />\r
-    <ClCompile Include="tzfmttst.cpp" />\r
+    <ClCompile Include="tzfmttst.cpp">\r
+           <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+    </ClCompile>\r
     <ClCompile Include="tzoffloc.cpp" />\r
     <ClCompile Include="tzregts.cpp" />\r
     <ClCompile Include="tzrulets.cpp" />\r
-    <ClCompile Include="tztest.cpp" />\r
+    <ClCompile Include="tztest.cpp">\r
+           <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+    </ClCompile>\r
     <ClCompile Include="windttst.cpp">\r
       <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>\r
       <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>\r
     <ClCompile Include="idnaref.cpp" />\r
     <ClCompile Include="nptrans.cpp" />\r
     <ClCompile Include="punyref.c" />\r
-    <ClCompile Include="testidn.cpp" />\r
+    <ClCompile Include="testidn.cpp">\r
+           <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+    </ClCompile>\r
     <ClCompile Include="testidna.cpp" />\r
     <ClCompile Include="uts46test.cpp" />\r
     <ClCompile Include="aliastst.cpp" />\r
     <ClCompile Include="loctest.cpp" />\r
     <ClCompile Include="restest.cpp" />\r
     <ClCompile Include="restsnew.cpp" />\r
-    <ClCompile Include="intltest.cpp" />\r
-    <ClCompile Include="itmajor.cpp" />\r
-    <ClCompile Include="itutil.cpp" />\r
+    <ClCompile Include="intltest.cpp">\r
+           <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+    </ClCompile>\r
+    <ClCompile Include="itmajor.cpp">\r
+           <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+    </ClCompile>\r
+    <ClCompile Include="itutil.cpp">\r
+           <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+    </ClCompile>\r
     <ClCompile Include="testutil.cpp" />\r
     <ClCompile Include="textfile.cpp" />\r
     <ClCompile Include="tokiter.cpp" />\r
     <ClCompile Include="winutil.cpp">\r
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>\r
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>\r
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>\r
-      <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>\r
+          <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
     </ClCompile>\r
     <ClCompile Include="canittst.cpp" />\r
     <ClCompile Include="normconf.cpp" />\r
-    <ClCompile Include="tstnorm.cpp" />\r
-    <ClCompile Include="tstnrapi.cpp" />\r
-    <ClCompile Include="ucdtest.cpp" />\r
+    <ClCompile Include="tstnorm.cpp">\r
+           <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+    </ClCompile>\r
+    <ClCompile Include="tstnrapi.cpp">\r
+           <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+    </ClCompile>\r
+    <ClCompile Include="ucdtest.cpp">\r
+           <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+    </ClCompile>\r
     <ClCompile Include="usettest.cpp" />\r
     <ClCompile Include="regextst.cpp" />\r
-    <ClCompile Include="icusvtst.cpp" />\r
+    <ClCompile Include="icusvtst.cpp">\r
+           <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+    </ClCompile>\r
     <ClCompile Include="citrtest.cpp" />\r
     <ClCompile Include="reptest.cpp" />\r
     <ClCompile Include="sfwdchit.cpp" />\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
   <ImportGroup Label="ExtensionTargets">\r
   </ImportGroup>\r
-</Project>
\ No newline at end of file
+</Project>\r
index bd9afbcecbc29d82b56ec45f6ae9573c1344d5ab..0d40a133a9ee962bc76ac839b5900c3ffd42c530 100644 (file)
@@ -15,7 +15,6 @@
 
 #include "unicode/utrace.h"
 #include "unicode/uclean.h"
-#include "umutex.h"
 #include "putilimp.h"
 
 /* NOTES:
@@ -122,7 +121,6 @@ int WARN_ON_MISSING_DATA = 0; /* Reduce data errs to warnings? */
 UTraceLevel ICU_TRACE = UTRACE_OFF;  /* ICU tracing level */
 size_t MINIMUM_MEMORY_SIZE_FAILURE = (size_t)-1; /* Minimum library memory allocation window that will fail. */
 size_t MAXIMUM_MEMORY_SIZE_FAILURE = (size_t)-1; /* Maximum library memory allocation window that will fail. */
-int32_t ALLOCATION_COUNT = 0;
 static const char *ARGV_0 = "[ALL]";
 static const char *XML_FILE_NAME=NULL;
 static char XML_PREFIX[256];
@@ -874,7 +872,6 @@ static void *U_CALLCONV ctest_libMalloc(const void *context, size_t size) {
     if (MINIMUM_MEMORY_SIZE_FAILURE <= size && size <= MAXIMUM_MEMORY_SIZE_FAILURE) {
         return NULL;
     }
-    umtx_atomic_inc(&ALLOCATION_COUNT);
     return malloc(size);
 }
 static void *U_CALLCONV ctest_libRealloc(const void *context, void *mem, size_t size) {
@@ -885,16 +882,9 @@ static void *U_CALLCONV ctest_libRealloc(const void *context, void *mem, size_t
         /*free(mem);*/ /* Realloc doesn't free on failure. */
         return NULL;
     }
-    if (mem == NULL) {
-        /* New allocation. */
-        umtx_atomic_inc(&ALLOCATION_COUNT);
-    }
     return realloc(mem, size);
 }
 static void U_CALLCONV ctest_libFree(const void *context, void *mem) {
-    if (mem != NULL) {
-        umtx_atomic_dec(&ALLOCATION_COUNT);
-    }
     free(mem);
 }
 
index 6997fee637bebcf85d3f0e467b4d30a534b18682..73e53726247fbefbe9fb8f196415eea1b73dd6d1 100644 (file)
@@ -92,7 +92,7 @@
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x86\Release/genbrk.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x86\Debug/genbrk.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>\r
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Release/genbrk.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Debug/genbrk.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>\r
index 2b2f505be4a8361a7ec1a13ddd485db3b2637263..18c63a69c155c7b49c910d694ce2d99c0a19574d 100644 (file)
@@ -90,7 +90,7 @@
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <PrecompiledHeader>\r
       </PrecompiledHeader>\r
       <AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>\r
       <MinimalRebuild>false</MinimalRebuild>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeader>\r
       </PrecompiledHeader>\r
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Release/gencfu.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Debug/gencfu.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>\r
index 6361240165769ce0a6194fb77ceb20b48068ac78..ca12c12f82411af1a37c9ebc0f7eb8a9428e9b82 100644 (file)
@@ -92,7 +92,7 @@
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x86\Release/gencnval.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x86\Debug/gencnval.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>\r
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Release/gencnval.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Debug/gencnval.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>\r
index dbcbf6f1b24361e91c5713115a0bf2270b8f549f..4245a0bba480eae29fdba2e2b0fc4a1dec24759a 100644 (file)
@@ -87,7 +87,7 @@
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x86\Release\gennorm2.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x86\Release\</AssemblerListingLocation>\r
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x86\Debug\gennorm2.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x86\Debug\</AssemblerListingLocation>\r
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Release\gennorm2.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Release\</AssemblerListingLocation>\r
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Debug\gennorm2.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Debug\</AssemblerListingLocation>\r
index 91752899369123f3b7e44b73f77c77fbe27722bc..533b546a050e15dd5b7f2b578ebaeb5e01313c04 100644 (file)
@@ -92,7 +92,7 @@
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x86\Release/gensprep.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x86\Debug/gensprep.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>\r
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <FunctionLevelLinking>true</FunctionLevelLinking>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Release/gensprep.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Debug/gensprep.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>\r
index 751a248f94cec81cd52019758a83ae1af24920e0..110dee900dd9a53ca8816ff02a990a44c3025399 100644 (file)
@@ -93,7 +93,7 @@
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x86\Debug/makeconv.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>\r
       <PreprocessorDefinitions>WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x86\Release/makeconv.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>\r
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <BufferSecurityCheck>true</BufferSecurityCheck>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Debug/makeconv.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>\r
       <PreprocessorDefinitions>WIN64;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <StringPooling>true</StringPooling>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
-      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r
+      <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>\r
       <PrecompiledHeaderOutputFile>.\x64\Release/makeconv.pch</PrecompiledHeaderOutputFile>\r
       <AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>\r
index 9bb123e10465a049b10d5ca2adbe90335729329d..8cb12778719c02bff481060a2983be84454302f7 100644 (file)
     <ClCompile Include="pkg_icu.cpp" />\r
     <ClCompile Include="pkgitems.cpp" />\r
     <ClCompile Include="ppucd.cpp" />\r
-    <ClCompile Include="swapimpl.cpp" />\r
+    <ClCompile Include="swapimpl.cpp">\r
+           <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+    </ClCompile>\r
     <ClCompile Include="toolutil.cpp">\r
       <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>\r
       <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>\r