/*
*******************************************************************************
-* Copyright (C) 1997-2011, International Business Machines Corporation and
+* Copyright (C) 1997-2013, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*
// defined in ucln_cmn.h
static icu::ICULocaleService* gService = NULL;
+static UInitOnce gInitOnce;
/**
* Release all static memory held by breakiterator.
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;
}
// -------------------------------------
<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
/*
*******************************************************************************
-* 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() {
}
/*
*******************************************************************************
-* Copyright (C) 2012, International Business Machines
+* Copyright (C) 2013, International Business Machines
* Corporation and others. All Rights Reserved.
*******************************************************************************
* dictionarydata.h
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.
/*
*******************************************************************************
*
-* Copyright (C) 1997-2011, International Business Machines
+* Copyright (C) 1997-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
#include "unicode/ures.h"
#include "cmemory.h"
#include "ucln_cmn.h"
+#include "uassert.h"
#include "umutex.h"
#include "uresimp.h"
static icu::Locale* availableLocaleList = NULL;
static int32_t availableLocaleListCount;
+static UInitOnce gInitOnce = U_INITONCE_INITIALIZER;
U_CDECL_BEGIN
availableLocaleList = NULL;
}
availableLocaleListCount = 0;
+ gInitOnce.reset();
return TRUE;
}
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;
}
static char** _installedLocales = NULL;
static int32_t _installedLocalesCount = 0;
+static UInitOnce _installedLocalesInitOnce;
/* ### Get available **************************************************/
_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
/*
*******************************************************************************
*
-* 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
/*
******************************************************************************
*
-* Copyright (C) 1997-2012, International Business Machines
+* Copyright (C) 1997-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
* 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.
}
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:
* 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.
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.
}
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:
/*
*******************************************************************************
*
-* Copyright (C) 2009-2012, International Business Machines
+* Copyright (C) 2009-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
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);
/*
*******************************************************************************
*
-* Copyright (C) 2009-2011, International Business Machines
+* Copyright (C) 2009-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
class U_COMMON_API Normalizer2Impl : public UMemory {
public:
Normalizer2Impl() : memory(NULL), normTrie(NULL) {
- canonIterDataSingleton.fInstance=NULL;
+ canonIterDataSingleton.reset();
}
~Normalizer2Impl();
/*
******************************************************************************
*
-* Copyright (C) 1997-2012, International Business Machines
+* Copyright (C) 1997-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
*/
#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
/** @} */
+
+/**
+ * \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 */
/*===========================================================================*/
/*
***************************************************************************
-* Copyright (C) 1999-2012 International Business Machines Corporation
+* Copyright (C) 1999-2013 International Business Machines Corporation
* and others. All rights reserved.
***************************************************************************
*/
// defined in ucln_cmn.h
static icu::UStack *gLanguageBreakFactories = NULL;
+static UInitOnce gLanguageBreakFactoriesInitOnce = U_INITONCE_INITIALIZER;
/**
* Release all static memory held by breakiterator.
delete gLanguageBreakFactories;
gLanguageBreakFactories = NULL;
}
+ gLanguageBreakFactoriesInitOnce.reset();
return TRUE;
}
U_CDECL_END
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;
}
/*
*******************************************************************************
*
-* Copyright (C) 1999-2011 International Business Machines
+* Copyright (C) 1999-2013 International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
#include "unicode/uobject.h"
#include "unicode/unistr.h"
+#include "umutex.h"
#include "utrie.h"
U_NAMESPACE_BEGIN
UTrie fTrie;
private:
- int32_t fRefCount;
+ atomic_int32_t fRefCount;
UDataMemory *fUDataMem;
UnicodeString fRuleString;
UBool fDontFreeData;
/*
**********************************************************************
-* Copyright (C) 1997-2011, International Business Machines
+* Copyright (C) 1997-2013, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*
#include "unicode/utypes.h"
#include "unicode/resbund.h"
+
+#include "mutex.h"
+#include "uassert.h"
#include "umutex.h"
#include "uresimp.h"
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);
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
return ures_getLocaleByType(fResource, type, &status);
}
-//eof
U_NAMESPACE_END
+//eof
-// 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.
}
-/* 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
/*
******************************************************************************
-* 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
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. */
/*
********************************************************************
* COPYRIGHT:
- * Copyright (c) 1996-2012, International Business Machines Corporation and
+ * Copyright (c) 1996-2013, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************
*
#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"
static const char **gAvailableConverters = NULL;
static uint16_t gAvailableConverterCount = 0;
+static UInitOnce gAvailableConvertersInitOnce = U_INITONCE_INITIALIZER;
#if !U_CHARSET_IS_UTF8
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 */
/* 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
/* 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);
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;
/*
******************************************************************************
*
-* Copyright (C) 1999-2012, International Business Machines
+* Copyright (C) 1999-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
#include "umutex.h"
#include "uarrsort.h"
+#include "uassert.h"
#include "udataswp.h"
#include "cstring.h"
#include "cmemory.h"
static const char DATA_TYPE[] = "icu";
static UDataMemory *gAliasData=NULL;
+static UInitOnce gAliasDataInitOnce = U_INITONCE_INITIALIZER;
enum {
tocLengthIndex=0,
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
/* character types relevant for ucnv_compareNames() */
enum {
- IGNORE,
+ UIGNORE,
ZERO,
NONZERO,
MINLETTER /* any values from here on are lowercase letter mappings */
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] = {
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)
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:
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:
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:
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:
#include "cmemory.h"
#include "cstring.h"
#include "putilimp.h"
+#include "uassert.h"
#include "ucln_cmn.h"
#include "ucmndata.h"
#include "udatamem.h"
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;
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]);
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;
}
/*
******************************************************************************
*
-* 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;
}
+
/*
**********************************************************************
-* 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*/
/*
******************************************************************************
*
-* Copyright (C) 1999-2011, International Business Machines
+* Copyright (C) 1999-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
#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"
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).
if(uCharNames) {
uCharNames = NULL;
}
+ gCharNamesInitOnce.reset();
gMaxNameLength=0;
return TRUE;
}
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) { \
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
* @internal
*/
friend Locale *locale_set_default_internal(const char *, UErrorCode& status);
+
+ friend void locale_available_init();
};
inline UBool
/*
******************************************************************************
*
-* Copyright (C) 1996-2011, International Business Machines Corporation
+* Copyright (C) 1996-2013, International Business Machines Corporation
* and others. All Rights Reserved.
*
******************************************************************************
UResourceBundle *fResource;
void constructForLocale(const UnicodeString& path, const Locale& locale, UErrorCode& error);
Locale *fLocale;
-
};
U_NAMESPACE_END
-// 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.
* 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.
/*
******************************************************************************
-* Copyright (C) 2001-2012, International Business Machines
+* Copyright (C) 2001-2013, International Business Machines
* Corporation and others. All Rights Reserved.
******************************************************************************
* file name: uclean.h
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;
* 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);
* 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);
* @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);
* @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);
* @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
/*
***************************************************************************
-* Copyright (C) 1999-2011, International Business Machines Corporation
+* Copyright (C) 1999-2013, International Business Machines Corporation
* and others. All Rights Reserved.
***************************************************************************
* Date Name Description
U_NAMESPACE_BEGIN
+// Forward Declarations.
+void UnicodeSet_initInclusion(int32_t src, UErrorCode &status);
+
class BMPSet;
class ParsePosition;
class RBBIRuleScanner;
UnicodeString& rebuiltPat,
UErrorCode& ec);
+ friend void UnicodeSet_initInclusion(int32_t src, UErrorCode &status);
static const UnicodeSet* getInclusions(int32_t src, UErrorCode &status);
/**
/*
*******************************************************************************
*
-* Copyright (C) 1999-2012, International Business Machines
+* Copyright (C) 1999-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
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);
* 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;
}
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 *
/*
******************************************************************************
-* Copyright (C) 1999-2012, International Business Machines Corporation and
+* Copyright (C) 1999-2013, International Business Machines Corporation and
* others. All Rights Reserved.
******************************************************************************
*
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
// 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;
}
}
}
#include "ulocimp.h"
#include "umutex.h"
#include "putilimp.h"
+#include "uassert.h"
/*
completely removed.
*/
static UHashtable *cache = NULL;
+static UInitOnce gCacheInitOnce;
static UMutex resbMutex = U_MUTEX_INITIALIZER;
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 */
/*
*******************************************************************************
*
- * Copyright (C) 2003-2012, International Business Machines
+ * Copyright (C) 2003-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
Static cache for already opened StringPrep profiles
*/
static UHashtable *SHARED_DATA_HASHTABLE = NULL;
+static UInitOnce gSharedDataInitOnce;
static UMutex usprepMutex = U_MUTEX_INITIALIZER;
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
/*
******************************************************************************
*
-* Copyright (C) 2001-2011, International Business Machines
+* Copyright (C) 2001-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
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;
}
## -*-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
<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
/*
*******************************************************************************
*
-* Copyright (C) 1998-2012, International Business Machines
+* Copyright (C) 1998-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
#include "cmemory.h"
#include "cstring.h"
#include "ucln_io.h"
+#include "mutex.h"
#include "umutex.h"
#include "unicode/ustring.h"
#include "unicode/uloc.h"
}
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];
}
-<?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
/********************************************************************
* COPYRIGHT:
- * Copyright (c) 1997-2012, International Business Machines Corporation and
+ * Copyright (c) 1997-2013, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
/********************************************************************************
} /* 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",
<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
/********************************************************************
* COPYRIGHT:
- * Copyright (c) 2003-2009, International Business Machines Corporation and
+ * Copyright (c) 2003-2013, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
/*
} ctest_AlignedMemory;
static void TestHeapFunctions(void);
-static void TestMutexFunctions(void);
-static void TestIncDecFunctions(void);
void addHeapMutexTest(TestNode **root);
addHeapMutexTest(TestNode** root)
{
addTest(root, &TestHeapFunctions, "hpmufn/TestHeapFunctions" );
- addTest(root, &TestMutexFunctions, "hpmufn/TestMutexFunctions" );
- addTest(root, &TestIncDecFunctions, "hpmufn/TestIncDecFunctions");
}
static int32_t gMutexFailures = 0;
}
-/*
- * 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);
-}
-
<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
#include "unicode/utrace.h"
#include "unicode/uclean.h"
-#include "umutex.h"
#include "putilimp.h"
/* NOTES:
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];
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) {
/*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);
}
<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
<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
<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
<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
<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
<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
<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