ICU-10051 Mutexes: introduce UInitOnce; remove UMTX_CHECK; replace all uses of UMTX_CHECK. All the directories this time.

X-SVN-Rev: 33788
This commit is contained in:
Andy Heninger 2013-06-01 03:37:16 +00:00
parent 978f71fe78
commit ae87a3acc2
47 changed files with 1609 additions and 1976 deletions

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 1997-2011, International Business Machines Corporation and
* Copyright (C) 1997-2013, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*
@ -271,6 +271,7 @@ U_NAMESPACE_END
// defined in ucln_cmn.h
static icu::ICULocaleService* gService = NULL;
static UInitOnce gInitOnce;
/**
* Release all static memory held by breakiterator.
@ -282,40 +283,33 @@ static UBool U_CALLCONV breakiterator_cleanup(void) {
delete gService;
gService = NULL;
}
gInitOnce.reset();
#endif
return TRUE;
}
U_CDECL_END
U_NAMESPACE_BEGIN
static void U_CALLCONV
initService(void) {
gService = new ICUBreakIteratorService();
ucln_common_registerCleanup(UCLN_COMMON_BREAKITERATOR, breakiterator_cleanup);
}
static ICULocaleService*
getService(void)
{
UBool needsInit;
UMTX_CHECK(NULL, (UBool)(gService == NULL), needsInit);
if (needsInit) {
ICULocaleService *tService = new ICUBreakIteratorService();
umtx_lock(NULL);
if (gService == NULL) {
gService = tService;
tService = NULL;
ucln_common_registerCleanup(UCLN_COMMON_BREAKITERATOR, breakiterator_cleanup);
}
umtx_unlock(NULL);
delete tService;
}
umtx_initOnce(gInitOnce, &initService);
return gService;
}
// -------------------------------------
static inline UBool
hasService(void)
{
UBool retVal;
UMTX_CHECK(NULL, gService != NULL, retVal);
return retVal;
return !gInitOnce.isReset() && getService() != NULL;
}
// -------------------------------------

View file

@ -90,7 +90,7 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x86\Release/common.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
@ -129,7 +129,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x86\Debug/common.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
@ -169,7 +169,7 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Release/common.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
@ -206,7 +206,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Debug/common.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>
@ -237,17 +237,24 @@
<ClCompile Include="ubidiln.c" />
<ClCompile Include="ubidiwrt.c" />
<ClCompile Include="ushape.cpp" />
<ClCompile Include="brkeng.cpp" />
<ClCompile Include="brkiter.cpp" />
<ClCompile Include="brkeng.cpp">
</ClCompile>
<ClCompile Include="brkiter.cpp">
</ClCompile>
<ClCompile Include="dictbe.cpp" />
<ClCompile Include="rbbi.cpp" />
<ClCompile Include="rbbidata.cpp" />
<ClCompile Include="rbbi.cpp">
</ClCompile>
<ClCompile Include="rbbidata.cpp">
</ClCompile>
<ClCompile Include="rbbinode.cpp" />
<ClCompile Include="rbbirb.cpp" />
<ClCompile Include="rbbirb.cpp">
</ClCompile>
<ClCompile Include="rbbiscan.cpp" />
<ClCompile Include="rbbisetb.cpp" />
<ClCompile Include="rbbistbl.cpp" />
<ClCompile Include="rbbitblb.cpp" />
<ClCompile Include="rbbistbl.cpp">
</ClCompile>
<ClCompile Include="rbbitblb.cpp">
</ClCompile>
<ClCompile Include="dictionarydata.cpp" />
<ClCompile Include="ubrk.cpp" />
<ClCompile Include="ucol_swp.cpp">
@ -278,7 +285,8 @@
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="mutex.cpp" />
<ClCompile Include="mutex.cpp">
</ClCompile>
<ClCompile Include="putil.cpp">
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
@ -302,13 +310,15 @@
</ClCompile>
<ClCompile Include="ucnv.c" />
<ClCompile Include="ucnv2022.cpp" />
<ClCompile Include="ucnv_bld.cpp" />
<ClCompile Include="ucnv_bld.cpp">
</ClCompile>
<ClCompile Include="ucnv_cb.c" />
<ClCompile Include="ucnv_cnv.c" />
<ClCompile Include="ucnv_ct.c" />
<ClCompile Include="ucnv_err.c" />
<ClCompile Include="ucnv_ext.cpp" />
<ClCompile Include="ucnv_io.cpp" />
<ClCompile Include="ucnv_io.cpp">
</ClCompile>
<ClCompile Include="ucnv_lmb.c" />
<ClCompile Include="ucnv_set.c" />
<ClCompile Include="ucnv_u16.c" />
@ -322,7 +332,8 @@
<ClCompile Include="ucnvlat1.c" />
<ClCompile Include="ucnvmbcs.c" />
<ClCompile Include="ucnvscsu.c" />
<ClCompile Include="ucnvsel.cpp" />
<ClCompile Include="ucnvsel.cpp">
</ClCompile>
<ClCompile Include="cmemory.c" />
<ClCompile Include="ucln_cmn.c">
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
@ -350,14 +361,18 @@
<ClCompile Include="punycode.cpp" />
<ClCompile Include="uidna.cpp" />
<ClCompile Include="uts46.cpp" />
<ClCompile Include="locavailable.cpp" />
<ClCompile Include="locavailable.cpp">
</ClCompile>
<ClCompile Include="locbased.cpp" />
<ClCompile Include="locdispnames.cpp" />
<ClCompile Include="locid.cpp" />
<ClCompile Include="locid.cpp">
</ClCompile>
<ClCompile Include="loclikely.cpp" />
<ClCompile Include="locresdata.cpp" />
<ClCompile Include="locutil.cpp" />
<ClCompile Include="resbund.cpp" />
<ClCompile Include="locutil.cpp">
</ClCompile>
<ClCompile Include="resbund.cpp">
</ClCompile>
<ClCompile Include="resbund_cnv.cpp" />
<ClCompile Include="ucat.c" />
<ClCompile Include="uloc.cpp" />
@ -365,19 +380,25 @@
<ClCompile Include="ures_cnv.c" />
<ClCompile Include="uresbund.cpp" />
<ClCompile Include="uresdata.c" />
<ClCompile Include="caniter.cpp" />
<ClCompile Include="caniter.cpp">
</ClCompile>
<ClCompile Include="filterednormalizer2.cpp" />
<ClCompile Include="normalizer2.cpp" />
<ClCompile Include="normalizer2impl.cpp" />
<ClCompile Include="normlzr.cpp" />
<ClCompile Include="normalizer2.cpp">
</ClCompile>
<ClCompile Include="normalizer2impl.cpp">
</ClCompile>
<ClCompile Include="normlzr.cpp">
</ClCompile>
<ClCompile Include="unorm.cpp" />
<ClCompile Include="unorm_it.c" />
<ClCompile Include="unormcmp.cpp" />
<ClCompile Include="bmpset.cpp" />
<ClCompile Include="patternprops.cpp" />
<ClCompile Include="propname.cpp" />
<ClCompile Include="propname.cpp">
</ClCompile>
<ClCompile Include="ruleiter.cpp" />
<ClCompile Include="ucase.cpp" />
<ClCompile Include="ucase.cpp">
</ClCompile>
<ClCompile Include="uchar.c" />
<ClCompile Include="unames.cpp" />
<ClCompile Include="unifilt.cpp" />
@ -394,13 +415,20 @@
<ClCompile Include="uset_props.cpp" />
<ClCompile Include="usetiter.cpp" />
<ClCompile Include="icuplug.c" />
<ClCompile Include="serv.cpp" />
<ClCompile Include="servlk.cpp" />
<ClCompile Include="servlkf.cpp" />
<ClCompile Include="servls.cpp" />
<ClCompile Include="servnotf.cpp" />
<ClCompile Include="servrbf.cpp" />
<ClCompile Include="servslkf.cpp" />
<ClCompile Include="serv.cpp">
</ClCompile>
<ClCompile Include="servlk.cpp">
</ClCompile>
<ClCompile Include="servlkf.cpp">
</ClCompile>
<ClCompile Include="servls.cpp">
</ClCompile>
<ClCompile Include="servnotf.cpp">
</ClCompile>
<ClCompile Include="servrbf.cpp">
</ClCompile>
<ClCompile Include="servslkf.cpp">
</ClCompile>
<ClCompile Include="usprep.cpp" />
<ClCompile Include="appendable.cpp" />
<ClCompile Include="bytestream.cpp" />
@ -438,7 +466,8 @@
<ClCompile Include="ustrtrns.cpp" />
<ClCompile Include="utext.cpp" />
<ClCompile Include="utf_impl.c" />
<ClCompile Include="listformatter.cpp" />
<ClCompile Include="listformatter.cpp">
</ClCompile>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="unicode\ubidi.h">
@ -1722,4 +1751,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2012, International Business Machines
* Copyright (C) 2013, International Business Machines
* Corporation and others. All Rights Reserved.
*******************************************************************************
* dictionarydata.h
@ -19,11 +19,16 @@
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() {
}

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2012, International Business Machines
* Copyright (C) 2013, International Business Machines
* Corporation and others. All Rights Reserved.
*******************************************************************************
* dictionarydata.h
@ -29,15 +29,15 @@ class BytesTrie;
class U_COMMON_API DictionaryData : public UMemory {
public:
static const int32_t TRIE_TYPE_BYTES = 0;
static const int32_t TRIE_TYPE_UCHARS = 1;
static const int32_t TRIE_TYPE_MASK = 7;
static const int32_t TRIE_HAS_VALUES = 8;
static const int32_t 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 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.

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
*
* Copyright (C) 1997-2011, International Business Machines
* Copyright (C) 1997-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -23,6 +23,7 @@
#include "unicode/ures.h"
#include "cmemory.h"
#include "ucln_cmn.h"
#include "uassert.h"
#include "umutex.h"
#include "uresimp.h"
@ -30,6 +31,7 @@
static icu::Locale* availableLocaleList = NULL;
static int32_t availableLocaleListCount;
static UInitOnce gInitOnce = U_INITONCE_INITIALIZER;
U_CDECL_BEGIN
@ -42,6 +44,7 @@ static UBool U_CALLCONV locale_available_cleanup(void)
availableLocaleList = NULL;
}
availableLocaleListCount = 0;
gInitOnce.reset();
return TRUE;
}
@ -50,40 +53,29 @@ U_CDECL_END
U_NAMESPACE_BEGIN
void U_CALLCONV locale_available_init() {
// This function is a friend of class Locale.
// This function is only invoked via umtx_initOnce().
// for now, there is a hardcoded list, so just walk through that list and set it up.
// Note: this function is a friend of class Locale.
availableLocaleListCount = uloc_countAvailable();
if(availableLocaleListCount) {
availableLocaleList = new Locale[availableLocaleListCount];
}
if (availableLocaleList == NULL) {
availableLocaleListCount= 0;
}
for (int32_t locCount=availableLocaleListCount-1; locCount>=0; --locCount) {
availableLocaleList[locCount].setFromPOSIXID(uloc_getAvailable(locCount));
}
ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE, locale_available_cleanup);
}
const Locale* U_EXPORT2
Locale::getAvailableLocales(int32_t& count)
{
// for now, there is a hardcoded list, so just walk through that list and set it up.
UBool needInit;
UMTX_CHECK(NULL, availableLocaleList == NULL, needInit);
if (needInit) {
int32_t locCount = uloc_countAvailable();
Locale *newLocaleList = 0;
if(locCount) {
newLocaleList = new Locale[locCount];
}
if (newLocaleList == NULL) {
count = 0;
return NULL;
}
count = locCount;
while(--locCount >= 0) {
newLocaleList[locCount].setFromPOSIXID(uloc_getAvailable(locCount));
}
umtx_lock(NULL);
if(availableLocaleList == 0) {
availableLocaleListCount = count;
availableLocaleList = newLocaleList;
newLocaleList = NULL;
ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE, locale_available_cleanup);
}
umtx_unlock(NULL);
delete []newLocaleList;
}
umtx_initOnce(gInitOnce, &locale_available_init);
count = availableLocaleListCount;
return availableLocaleList;
}
@ -104,6 +96,7 @@ static const char _kIndexTag[] = "InstalledLocales";
static char** _installedLocales = NULL;
static int32_t _installedLocalesCount = 0;
static UInitOnce _installedLocalesInitOnce;
/* ### Get available **************************************************/
@ -115,57 +108,51 @@ static UBool U_CALLCONV uloc_cleanup(void) {
_installedLocales = NULL;
_installedLocalesCount = 0;
_installedLocalesInitOnce.reset();
uprv_free(temp);
}
return TRUE;
}
// Load Installed Locales. This function will be called exactly once
// via the initOnce mechanism.
static void U_CALLCONV loadInstalledLocales() {
UResourceBundle *indexLocale = NULL;
UResourceBundle installed;
UErrorCode status = U_ZERO_ERROR;
int32_t i = 0;
int32_t localeCount;
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);
}
static void _load_installedLocales()
{
UBool localesLoaded;
UMTX_CHECK(NULL, _installedLocales != NULL, localesLoaded);
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);
}
}
ures_close(&installed);
ures_close(indexLocale);
}
umtx_initOnce(_installedLocalesInitOnce, &loadInstalledLocales);
}
U_CAPI const char* U_EXPORT2

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
*
* Copyright (C) 2008-2011, International Business Machines
* Copyright (C) 2008-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -18,114 +18,63 @@
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

View file

@ -1,7 +1,7 @@
/*
******************************************************************************
*
* Copyright (C) 1997-2012, International Business Machines
* Copyright (C) 1997-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
@ -90,27 +90,26 @@ typedef void *InstantiatorFn(const void *context, UErrorCode &errorCode);
* Define a static SimpleSingleton instance via the STATIC_SIMPLE_SINGLETON macro.
*/
struct SimpleSingleton {
void *fInstance;
void *fInstance;
UInitOnce fInitOnce;
/**
* Returns the singleton instance, or NULL if it could not be created.
* Calls the instantiator with the context if the instance has not been
* created yet. In a race condition, the duplicate may not be NULL.
* The caller must delete the duplicate.
* The caller need not initialize the duplicate before the call.
* created yet.
*/
void *getInstance(InstantiatorFn *instantiator, const void *context,
void *&duplicate,
UErrorCode &errorCode);
/**
* Resets the fields. The caller must have deleted the singleton instance.
* Not mutexed.
* Call this from a cleanup function.
*/
void reset() { fInstance=NULL; }
void reset() { fInstance=NULL; fInitOnce.reset(); }
};
#define STATIC_SIMPLE_SINGLETON(name) static SimpleSingleton name={ NULL }
#define SIMPLE_SINGLETON_INITIALIZER {NULL, U_INITONCE_INITIALIZER}
#define STATIC_SIMPLE_SINGLETON(name) static SimpleSingleton name = SIMPLE_SINGLETON_INITIALIZER
/**
* Handy wrapper for a SimpleSingleton.
@ -127,9 +126,7 @@ public:
}
T *getInstance(InstantiatorFn *instantiator, const void *context,
UErrorCode &errorCode) {
void *duplicate;
T *instance=(T *)singleton.getInstance(instantiator, context, duplicate, errorCode);
delete (T *)duplicate;
T *instance=(T *)singleton.getInstance(instantiator, context, errorCode);
return instance;
}
private:
@ -143,20 +140,18 @@ private:
* Define a static TriStateSingleton instance via the STATIC_TRI_STATE_SINGLETON macro.
*/
struct TriStateSingleton {
void *fInstance;
UErrorCode fErrorCode;
void *fInstance;
UErrorCode fErrorCode;
UInitOnce fInitOnce;
/**
* Returns the singleton instance, or NULL if it could not be created.
* Calls the instantiator with the context if the instance has not been
* created yet. In a race condition, the duplicate may not be NULL.
* The caller must delete the duplicate.
* The caller need not initialize the duplicate before the call.
* created yet.
* The singleton creation is only attempted once. If it fails,
* the singleton will then always return NULL.
*/
void *getInstance(InstantiatorFn *instantiator, const void *context,
void *&duplicate,
UErrorCode &errorCode);
/**
* Resets the fields. The caller must have deleted the singleton instance.
@ -166,7 +161,7 @@ struct TriStateSingleton {
void reset();
};
#define STATIC_TRI_STATE_SINGLETON(name) static TriStateSingleton name={ NULL, U_ZERO_ERROR }
#define STATIC_TRI_STATE_SINGLETON(name) static TriStateSingleton name={ NULL, U_ZERO_ERROR, U_INITONCE_INITIALIZER }
/**
* Handy wrapper for a TriStateSingleton.
@ -183,9 +178,7 @@ public:
}
T *getInstance(InstantiatorFn *instantiator, const void *context,
UErrorCode &errorCode) {
void *duplicate;
T *instance=(T *)singleton.getInstance(instantiator, context, duplicate, errorCode);
delete (T *)duplicate;
T *instance=(T *)singleton.getInstance(instantiator, context, errorCode);
return instance;
}
private:

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
*
* Copyright (C) 2009-2012, International Business Machines
* Copyright (C) 2009-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -1796,10 +1796,8 @@ public:
CanonIterDataSingleton(SimpleSingleton &s, Normalizer2Impl &ni, UErrorCode &ec) :
singleton(s), impl(ni), errorCode(ec) {}
CanonIterData *getInstance(UErrorCode &errorCode) {
void *duplicate;
CanonIterData *instance=
(CanonIterData *)singleton.getInstance(createInstance, this, duplicate, errorCode);
delete (CanonIterData *)duplicate;
(CanonIterData *)singleton.getInstance(createInstance, this, errorCode);
return instance;
}
static void *createInstance(const void *context, UErrorCode &errorCode);

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
*
* Copyright (C) 2009-2011, International Business Machines
* Copyright (C) 2009-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -216,7 +216,7 @@ private:
class U_COMMON_API Normalizer2Impl : public UMemory {
public:
Normalizer2Impl() : memory(NULL), normTrie(NULL) {
canonIterDataSingleton.fInstance=NULL;
canonIterDataSingleton.reset();
}
~Normalizer2Impl();

View file

@ -1,7 +1,7 @@
/*
******************************************************************************
*
* Copyright (C) 1997-2012, International Business Machines
* Copyright (C) 1997-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
@ -183,7 +183,13 @@ typedef size_t uintptr_t;
*/
#ifdef U_HAVE_GCC_ATOMICS
/* Use the predefined value. */
#elif U_GCC_MAJOR_MINOR >= 404
#elif U_PLATFORM == U_PF_MINGW
#define U_HAVE_GCC_ATOMICS 0
#elif U_GCC_MAJOR_MINOR >= 404 || defined(__clang__)
/* TODO: Intel icc and IBM xlc on AIX also support gcc atomics. (Intel originated them.)
* Add them for these compilers.
* Note: Clang sets __GNUC__ defines for version 4.2, so misses the 4.4 test here.
*/
# define U_HAVE_GCC_ATOMICS 1
#else
# define U_HAVE_GCC_ATOMICS 0
@ -191,6 +197,34 @@ typedef size_t uintptr_t;
/** @} */
/**
* \def U_HAVE_STD_ATOMICS
* Defines whether the standard C++11 <atomic> is available.
* @internal
*/
#ifdef U_HAVE_STD_ATOMICS
/* Use the predefined value. */
#elif defined(__cplusplus) && __cplusplus>=201103L
/* C++11, so we should have atomics, except for specific platforms or compilers. */
#if __clang__ && defined(__apple_build_version__) && __clang_major__==4 && __clang_minor__<=1
/* Apple Clang 4.1, based on public llvm 3.1. Atomics are not fully implemented. */
# define U_HAVE_STD_ATOMICS 0
#elif __clang__ && __clang_major__==3 && __clang_minor__<=1
/* Clang 3.1. Atomics not fully implemented. */
# define U_HAVE_STD_ATOMICS 0
#else
# define U_HAVE_STD_ATOMICS 1
#endif
#else
/* Not C++ 11 */
# define U_HAVE_STD_ATOMICS 0
#endif
/*===========================================================================*/
/** @{ Code alignment */
/*===========================================================================*/

View file

@ -1,6 +1,6 @@
/*
***************************************************************************
* Copyright (C) 1999-2012 International Business Machines Corporation
* Copyright (C) 1999-2013 International Business Machines Corporation
* and others. All rights reserved.
***************************************************************************
*/
@ -1793,6 +1793,7 @@ U_NAMESPACE_END
// defined in ucln_cmn.h
static icu::UStack *gLanguageBreakFactories = NULL;
static UInitOnce gLanguageBreakFactoriesInitOnce = U_INITONCE_INITIALIZER;
/**
* Release all static memory held by breakiterator.
@ -1803,6 +1804,7 @@ static UBool U_CALLCONV breakiterator_cleanup_dict(void) {
delete gLanguageBreakFactories;
gLanguageBreakFactories = NULL;
}
gLanguageBreakFactoriesInitOnce.reset();
return TRUE;
}
U_CDECL_END
@ -1814,35 +1816,28 @@ static void U_CALLCONV _deleteFactory(void *obj) {
U_CDECL_END
U_NAMESPACE_BEGIN
static 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) {
gLanguageBreakFactories->push(extra, status);
}
#endif
}
ucln_common_registerCleanup(UCLN_COMMON_BREAKITERATOR_DICT, breakiterator_cleanup_dict);
}
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);
#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);
}
umtx_unlock(NULL);
delete factories;
}
umtx_initOnce(gLanguageBreakFactoriesInitOnce, &initLanguageFactories);
if (gLanguageBreakFactories == NULL) {
return NULL;
}

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
*
* Copyright (C) 1999-2011 International Business Machines
* Copyright (C) 1999-2013 International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -49,6 +49,7 @@ ubrk_swap(const UDataSwapper *ds,
#include "unicode/uobject.h"
#include "unicode/unistr.h"
#include "umutex.h"
#include "utrie.h"
U_NAMESPACE_BEGIN
@ -180,7 +181,7 @@ public:
UTrie fTrie;
private:
int32_t fRefCount;
atomic_int32_t fRefCount;
UDataMemory *fUDataMem;
UnicodeString fRuleString;
UBool fDontFreeData;

View file

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (C) 1997-2011, International Business Machines
* Copyright (C) 1997-2013, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*
@ -48,6 +48,9 @@
#include "unicode/utypes.h"
#include "unicode/resbund.h"
#include "mutex.h"
#include "uassert.h"
#include "umutex.h"
#include "uresimp.h"
@ -216,6 +219,10 @@ ResourceBundle& ResourceBundle::operator=(const ResourceBundle& other)
ures_close(fResource);
fResource = NULL;
}
if (fLocale != NULL) {
delete fLocale;
fLocale = NULL;
}
UErrorCode status = U_ZERO_ERROR;
if (other.fResource) {
fResource = ures_copyResb(0, other.fResource, &status);
@ -367,28 +374,17 @@ void ResourceBundle::getVersion(UVersionInfo versionInfo) const {
ures_getVersion(fResource, versionInfo);
}
const Locale &ResourceBundle::getLocale(void) const
{
UBool needInit;
UMTX_CHECK(NULL, (fLocale == NULL), needInit);
if(needInit) {
UErrorCode status = U_ZERO_ERROR;
const char *localeName = ures_getLocaleInternal(fResource, &status);
Locale *tLocale = new Locale(localeName);
// Null pointer check
if (tLocale == NULL) {
return Locale::getDefault(); // Return default locale if one could not be created.
}
umtx_lock(NULL);
ResourceBundle *me = (ResourceBundle *)this; // semantically const
if (me->fLocale == NULL) {
me->fLocale = tLocale;
tLocale = NULL;
}
umtx_unlock(NULL);
delete tLocale;
static UMutex gLocaleLock = U_MUTEX_INITIALIZER;
const Locale &ResourceBundle::getLocale(void) const {
Mutex lock(&gLocaleLock);
if (fLocale != NULL) {
return *fLocale;
}
return *fLocale;
UErrorCode status = U_ZERO_ERROR;
const char *localeName = ures_getLocaleInternal(fResource, &status);
ResourceBundle *ncThis = const_cast<ResourceBundle *>(this);
ncThis->fLocale = new Locale(localeName);
return ncThis->fLocale != NULL ? *ncThis->fLocale : Locale::getDefault();
}
const Locale ResourceBundle::getLocale(ULocDataLocaleType type, UErrorCode &status) const
@ -396,5 +392,5 @@ const Locale ResourceBundle::getLocale(ULocDataLocaleType type, UErrorCode &stat
return ures_getLocaleByType(fResource, type, &status);
}
//eof
U_NAMESPACE_END
//eof

View file

@ -1,4 +1,4 @@
// Copyright (C) 2009-2012, International Business Machines
// Copyright (C) 2009-2013, International Business Machines
// Corporation and others. All Rights Reserved.
//
// Copyright 2004 and onwards Google Inc.
@ -68,15 +68,6 @@ operator==(const StringPiece& x, const StringPiece& y) {
}
/* Microsft Visual Studios <= 8.0 complains about redefinition of this
* static const class variable. However, the C++ standard states that this
* definition is correct. Perhaps there is a bug in the Microsoft compiler.
* This is not an issue on any other compilers (that we know of) including
* Visual Studios 9.0.
* Cygwin with MSVC 9.0 also complains here about redefinition.
*/
#if (!defined(_MSC_VER) || (_MSC_VER >= 1500)) && !defined(CYGWINMSVC)
const int32_t StringPiece::npos;
#endif
const int32_t StringPiece::npos = 0x7fffffff;
U_NAMESPACE_END

View file

@ -1,6 +1,6 @@
/*
******************************************************************************
* Copyright (C) 2001-2012, International Business Machines
* Copyright (C) 2001-2013, International Business Machines
* Corporation and others. All Rights Reserved.
******************************************************************************
* file name: ucln_cmn.c
@ -58,7 +58,6 @@ u_cleanup(void)
ucln_lib_cleanup();
umtx_cleanup();
cmemory_cleanup(); /* undo any heap functions set by u_setMemoryFunctions(). */
gICUInitialized = FALSE;
UTRACE_EXIT(); /* Must be before utrace_cleanup(), which turns off tracing. */

View file

@ -1,7 +1,7 @@
/*
********************************************************************
* COPYRIGHT:
* Copyright (c) 1996-2012, International Business Machines Corporation and
* Copyright (c) 1996-2013, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************
*
@ -27,7 +27,9 @@
#include "unicode/udata.h"
#include "unicode/ucnv.h"
#include "unicode/uloc.h"
#include "mutex.h"
#include "putilimp.h"
#include "uassert.h"
#include "utracimp.h"
#include "ucnv_io.h"
#include "ucnv_bld.h"
@ -165,6 +167,7 @@ static UMutex cnvCacheMutex = U_MUTEX_INITIALIZER; /* Mutex for synchronizing c
static const char **gAvailableConverters = NULL;
static uint16_t gAvailableConverterCount = 0;
static UInitOnce gAvailableConvertersInitOnce = U_INITONCE_INITIALIZER;
#if !U_CHARSET_IS_UTF8
@ -187,15 +190,18 @@ static UBool gDefaultConverterContainsOption;
static const char DATA_TYPE[] = "cnv";
/* ucnv_flushAvailableConverterCache. This is only called from ucnv_cleanup().
* If it is ever to be called from elsewhere, synchronization
* will need to be considered.
*/
static void
ucnv_flushAvailableConverterCache() {
gAvailableConverterCount = 0;
if (gAvailableConverters) {
umtx_lock(&cnvCacheMutex);
gAvailableConverterCount = 0;
uprv_free((char **)gAvailableConverters);
gAvailableConverters = NULL;
umtx_unlock(&cnvCacheMutex);
}
gAvailableConvertersInitOnce.reset();
}
/* ucnv_cleanup - delete all storage held by the converter cache, except any */
@ -1110,59 +1116,46 @@ ucnv_flushCache ()
/* available converters list --------------------------------------------------- */
static UBool haveAvailableConverterList(UErrorCode *pErrorCode) {
int needInit;
UMTX_CHECK(&cnvCacheMutex, (gAvailableConverters == NULL), needInit);
if (needInit) {
UConverter tempConverter;
UEnumeration *allConvEnum = NULL;
uint16_t idx;
uint16_t localConverterCount;
uint16_t allConverterCount;
UErrorCode localStatus;
const char *converterName;
const char **localConverterList;
static void U_CALLCONV initAvailableConvertersList(UErrorCode &errCode) {
U_ASSERT(gAvailableConverterCount == 0);
U_ASSERT(gAvailableConverters == NULL);
allConvEnum = ucnv_openAllNames(pErrorCode);
allConverterCount = uenum_count(allConvEnum, pErrorCode);
if (U_FAILURE(*pErrorCode)) {
return FALSE;
}
/* 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;
}
/* 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));
localConverterCount = 0;
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);
umtx_lock(&cnvCacheMutex);
if (gAvailableConverters == NULL) {
gAvailableConverterCount = localConverterCount;
gAvailableConverters = localConverterList;
ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
}
else {
uprv_free((char **)localConverterList);
}
umtx_unlock(&cnvCacheMutex);
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;
}
return TRUE;
/* 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;
}
/* 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));
gAvailableConverterCount = 0;
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;
}
}
uenum_close(allConvEnum);
}
static UBool haveAvailableConverterList(UErrorCode *pErrorCode) {
umtx_initOnce(gAvailableConvertersInitOnce, &initAvailableConvertersList, *pErrorCode);
return U_SUCCESS(*pErrorCode);
}
U_CFUNC uint16_t
@ -1228,6 +1221,9 @@ internalSetName(const char *name, UErrorCode *status) {
/* gDefaultConverterName MUST be the last global var set by this function. */
/* It is the variable checked in ucnv_getDefaultName() to see if initialization is required. */
// But there is nothing here preventing that from being reordered, either by the compiler
// or hardware. I'm adding the mutex to ucnv_getDefaultName for now. UMTX_CHECK is not enough.
// -- Andy
gDefaultConverterName = gDefaultConverterNameBuffer;
ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
@ -1253,10 +1249,13 @@ ucnv_getDefaultName() {
const char *name;
/*
Multiple calls to ucnv_getDefaultName must be thread safe,
Concurrent calls to ucnv_getDefaultName must be thread safe,
but ucnv_setDefaultName is not thread safe.
*/
UMTX_CHECK(&cnvCacheMutex, gDefaultConverterName, name);
{
icu::Mutex lock(&cnvCacheMutex);
name = gDefaultConverterName;
}
if(name==NULL) {
UErrorCode errorCode = U_ZERO_ERROR;
UConverter *cnv = NULL;

View file

@ -1,7 +1,7 @@
/*
******************************************************************************
*
* Copyright (C) 1999-2012, International Business Machines
* Copyright (C) 1999-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
@ -36,6 +36,7 @@
#include "umutex.h"
#include "uarrsort.h"
#include "uassert.h"
#include "udataswp.h"
#include "cstring.h"
#include "cmemory.h"
@ -172,6 +173,7 @@ static const char DATA_NAME[] = "cnvalias";
static const char DATA_TYPE[] = "icu";
static UDataMemory *gAliasData=NULL;
static UInitOnce gAliasDataInitOnce = U_INITONCE_INITIALIZER;
enum {
tocLengthIndex=0,
@ -218,113 +220,97 @@ static UBool U_CALLCONV ucnv_io_cleanup(void)
udata_close(gAliasData);
gAliasData = NULL;
}
gAliasDataInitOnce.reset();
uprv_memset(&gMainTable, 0, sizeof(gMainTable));
return TRUE; /* Everything was cleaned up */
}
static void U_CALLCONV initAliasData(UErrorCode &errCode) {
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);
U_ASSERT(gAliasData == NULL);
data = udata_openChoice(NULL, DATA_TYPE, DATA_NAME, isAcceptable, NULL, &errCode);
if(U_FAILURE(errCode)) {
return;
}
sectionSizes = (const uint32_t *)udata_getMemory(data);
table = (const uint16_t *)sectionSizes;
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 = tableStart * (sizeof(uint32_t)/sizeof(uint16_t)) + (sizeof(uint32_t)/sizeof(uint16_t));
gMainTable.converterList = table + currOffset;
currOffset += gMainTable.converterListSize;
gMainTable.tagList = table + currOffset;
currOffset += gMainTable.tagListSize;
gMainTable.aliasList = table + currOffset;
currOffset += gMainTable.aliasListSize;
gMainTable.untaggedConvArray = table + currOffset;
currOffset += gMainTable.untaggedConvArraySize;
gMainTable.taggedAliasArray = table + currOffset;
/* aliasLists is a 1's based array, but it has a padding character */
currOffset += gMainTable.taggedAliasArraySize;
gMainTable.taggedAliasLists = 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.optionTableSize;
gMainTable.stringTable = table + currOffset;
currOffset += gMainTable.stringTableSize;
gMainTable.normalizedStringTable = ((gMainTable.optionTable->stringNormalizationType == UCNV_IO_UNNORMALIZED)
? gMainTable.stringTable : (table + currOffset));
}
static UBool
haveAliasData(UErrorCode *pErrorCode) {
int needInit;
if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
return FALSE;
}
UMTX_CHECK(NULL, (gAliasData==NULL), needInit);
/* 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;
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];
}
currOffset = tableStart * (sizeof(uint32_t)/sizeof(uint16_t)) + (sizeof(uint32_t)/sizeof(uint16_t));
gMainTable.converterList = table + currOffset;
currOffset += gMainTable.converterListSize;
gMainTable.tagList = table + currOffset;
currOffset += gMainTable.tagListSize;
gMainTable.aliasList = table + currOffset;
currOffset += gMainTable.aliasListSize;
gMainTable.untaggedConvArray = table + currOffset;
currOffset += gMainTable.untaggedConvArraySize;
gMainTable.taggedAliasArray = table + currOffset;
/* aliasLists is a 1's based array, but it has a padding character */
currOffset += gMainTable.taggedAliasArraySize;
gMainTable.taggedAliasLists = 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.optionTableSize;
gMainTable.stringTable = table + currOffset;
currOffset += gMainTable.stringTableSize;
gMainTable.normalizedStringTable = ((gMainTable.optionTable->stringNormalizationType == UCNV_IO_UNNORMALIZED)
? gMainTable.stringTable : (table + currOffset));
ucln_common_registerCleanup(UCLN_COMMON_UCNV_IO, ucnv_io_cleanup);
gAliasData = data;
data=NULL;
}
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;
umtx_initOnce(gAliasDataInitOnce, &initAliasData, *pErrorCode);
return U_SUCCESS(*pErrorCode);
}
static inline UBool
@ -351,7 +337,7 @@ static uint32_t getTagNumber(const char *tagname) {
/* character types relevant for ucnv_compareNames() */
enum {
IGNORE,
UIGNORE,
ZERO,
NONZERO,
MINLETTER /* any values from here on are lowercase letter mappings */
@ -369,7 +355,7 @@ static const uint8_t asciiTypes[128] = {
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0, 0, 0, 0, 0
};
#define GET_ASCII_TYPE(c) ((int8_t)(c) >= 0 ? asciiTypes[(uint8_t)c] : (uint8_t)IGNORE)
#define GET_ASCII_TYPE(c) ((int8_t)(c) >= 0 ? asciiTypes[(uint8_t)c] : (uint8_t)UIGNORE)
/* character types for EBCDIC 80..FF */
static const uint8_t ebcdicTypes[128] = {
@ -383,7 +369,7 @@ static const uint8_t ebcdicTypes[128] = {
ZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, 0, 0, 0, 0, 0, 0
};
#define GET_EBCDIC_TYPE(c) ((int8_t)(c) < 0 ? ebcdicTypes[(c)&0x7f] : (uint8_t)IGNORE)
#define GET_EBCDIC_TYPE(c) ((int8_t)(c) < 0 ? ebcdicTypes[(c)&0x7f] : (uint8_t)UIGNORE)
#if U_CHARSET_FAMILY==U_ASCII_FAMILY
# define GET_CHAR_TYPE(c) GET_ASCII_TYPE(c)
@ -404,7 +390,7 @@ ucnv_io_stripASCIIForCompare(char *dst, const char *name) {
while ((c1 = *name++) != 0) {
type = GET_ASCII_TYPE(c1);
switch (type) {
case IGNORE:
case UIGNORE:
afterDigit = FALSE;
continue; /* ignore all but letters and digits */
case ZERO:
@ -439,7 +425,7 @@ ucnv_io_stripEBCDICForCompare(char *dst, const char *name) {
while ((c1 = *name++) != 0) {
type = GET_EBCDIC_TYPE(c1);
switch (type) {
case IGNORE:
case UIGNORE:
afterDigit = FALSE;
continue; /* ignore all but letters and digits */
case ZERO:
@ -496,7 +482,7 @@ ucnv_compareNames(const char *name1, const char *name2) {
while ((c1 = *name1++) != 0) {
type = GET_CHAR_TYPE(c1);
switch (type) {
case IGNORE:
case UIGNORE:
afterDigit1 = FALSE;
continue; /* ignore all but letters and digits */
case ZERO:
@ -520,7 +506,7 @@ ucnv_compareNames(const char *name1, const char *name2) {
while ((c2 = *name2++) != 0) {
type = GET_CHAR_TYPE(c2);
switch (type) {
case IGNORE:
case UIGNORE:
afterDigit2 = FALSE;
continue; /* ignore all but letters and digits */
case ZERO:

View file

@ -30,6 +30,7 @@ might have to #include some other header
#include "cmemory.h"
#include "cstring.h"
#include "putilimp.h"
#include "uassert.h"
#include "ucln_cmn.h"
#include "ucmndata.h"
#include "udatamem.h"
@ -106,6 +107,7 @@ static UDataMemory *gCommonICUDataArray[10] = { NULL };
static UBool gHaveTriedToLoadCommonData = FALSE; /* See extendICUData(). */
static UHashtable *gCommonDataCache = NULL; /* Global hash table of opened ICU data files. */
static UInitOnce gCommonDataCacheInitOnce = U_INITONCE_INITIALIZER;
static UDataFileAccess gDataFileAccess = UDATA_DEFAULT_ACCESS;
@ -118,6 +120,7 @@ udata_cleanup(void)
uhash_close(gCommonDataCache); /* Table owns the contents, and will delete them. */
gCommonDataCache = NULL; /* Cleanup is not thread safe. */
}
gCommonDataCacheInitOnce.reset();
for (i = 0; i < LENGTHOF(gCommonICUDataArray) && gCommonICUDataArray[i] != NULL; ++i) {
udata_close(gCommonICUDataArray[i]);
@ -262,42 +265,26 @@ static void U_CALLCONV DataCacheElement_deleter(void *pDCEl) {
uprv_free(pDCEl); /* delete 'this' */
}
/* udata_getCacheHashTable()
* Get the hash table used to store the data cache entries.
* Lazy create it if it doesn't yet exist.
*/
static UHashtable *udata_getHashTable() {
UErrorCode err = U_ZERO_ERROR;
UBool cacheIsInitialized;
UHashtable *tHT = NULL;
UMTX_CHECK(NULL, (gCommonDataCache != NULL), cacheIsInitialized);
if (cacheIsInitialized) {
return gCommonDataCache;
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;
}
tHT = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &err);
/* Check for null pointer. */
if (tHT == NULL) {
return NULL; /* TODO: Handle this error better. */
}
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;
}

View file

@ -1,7 +1,7 @@
/*
******************************************************************************
*
* Copyright (C) 1997-2012, International Business Machines
* Copyright (C) 1997-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
@ -18,152 +18,122 @@
******************************************************************************
*/
#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
//-------------------------------------------------------------------------------------------
//
// 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)
//
//-------------------------------------------------------------------------------------------
#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
// 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.
//
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);
}
}
}
// 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);
}
static void winMutexInit(CRITICAL_SECTION *cs) {
InitializeCriticalSection(cs);
return;
}
U_CAPI void U_EXPORT2
umtx_lock(UMutex *mutex) {
if (mutex == NULL) {
mutex = &globalMutex;
}
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;
}
LeaveCriticalSection(&mutex->fCS);
}
#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
#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)
#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.
//-------------------------------------------------------------------------------------------
//
// 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.
// POSIX specific definitions
//
static const int MUTEX_LIST_LIMIT = 100;
static UMutex *gMutexList[MUTEX_LIST_LIMIT];
static int gMutexListSize = 0;
//-------------------------------------------------------------------------------------------
# include <pthread.h>
/*
* 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;
}
(*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);
}
#if defined(POSIX)
//
// POSIX implementation of UMutex.
//
// Each UMutex has a corresponding pthread_mutex_t.
// Each UMutex consists of a pthread_mutex_t.
// All are statically initialized and ready for use.
// There is no runtime mutex initialization code needed.
@ -172,17 +142,9 @@ 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
}
int sysErr = pthread_mutex_lock(&mutex->fMutex);
(void)sysErr; // Suppress unused variable warnings.
U_ASSERT(sysErr == 0);
}
@ -192,292 +154,161 @@ 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
}
int sysErr = pthread_mutex_unlock(&mutex->fMutex);
(void)sysErr; // Suppress unused variable warnings.
U_ASSERT(sysErr == 0);
}
#elif U_PLATFORM_HAS_WIN32_API
static pthread_mutex_t initMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t initCondition = PTHREAD_COND_INITIALIZER;
// 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.
//
// Windows implementation of UMutex.
// 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.
//
// Each UMutex has a corresponding Windows CRITICAL_SECTION.
// CRITICAL_SECTIONS must be initialized before use. This is done
// with a InitOnceExcuteOnce operation.
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;
}
}
// 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.
//
// 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.
// 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.
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;
}
/*
* 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);
}
}
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);
}
}
#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;
}
/* 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;
}
// 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;
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
#endif // Platform #define chain.
//-------------------------------------------------------------------------------
//
// 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.
//
//--------------------------------------------------------------------------------
/*-----------------------------------------------------------------
*
* Atomic Increment and Decrement
* umtx_atomic_inc
* umtx_atomic_dec
*
*----------------------------------------------------------------*/
/* 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)
#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;
}
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);
}
#endif
//--------------------------------------------------------------------------
//
// Deprecated functions for setting user mutexes.
//
//--------------------------------------------------------------------------
U_DEPRECATED void U_EXPORT2
u_setMutexFunctions(const void * /*context */, UMtxInitFn *, UMtxFn *,
UMtxFn *, UMtxFn *, UErrorCode *status) {
if (U_SUCCESS(*status)) {
*status = U_UNSUPPORTED_ERROR;
}
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;
}

View file

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (C) 1997-2012, International Business Machines
* Copyright (C) 1997-2013, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*
@ -22,208 +22,346 @@
#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
# 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
/*
* 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
*/
#ifndef ANNOTATE_HAPPENS_BEFORE
# define ANNOTATE_HAPPENS_BEFORE(obj)
# define ANNOTATE_HAPPENS_AFTER(obj)
# define ANNOTATE_UNPROTECTED_READ(x) (x)
#endif
#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); \
}
# ifndef NOMINMAX
# define NOMINMAX
# endif
#endif
# include <windows.h>
#ifndef UMTX_ACQUIRE_BARRIER
# define UMTX_ACQUIRE_BARRIER UMTX_FULL_BARRIER
#endif
typedef volatile LONG atomic_int32_t;
#define ATOMIC_INT32_T_INITIALIZER(val) val
#ifndef UMTX_RELEASE_BARRIER
# define UMTX_RELEASE_BARRIER UMTX_FULL_BARRIER
#endif
#ifdef __cplusplus
inline int32_t umtx_loadAcquire(atomic_int32_t &var) {
return InterlockedCompareExchange(&var, 0, 0);
}
/**
* \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
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
/*
* gcc atomic ops. These are available on several other compilers as well.
*/
#define UMTX_CHECK(pMutex, expression, result) \
{ \
(result)=(expression); \
UMTX_ACQUIRE_BARRIER; \
typedef int32_t atomic_int32_t;
#define ATOMIC_INT32_T_INITIALIZER(val) val
#ifdef __cplusplus
inline int32_t umtx_loadAcquire(atomic_int32_t &var) {
int32_t val = var;
__sync_synchronize();
return val;
}
inline void umtx_storeRelease(atomic_int32_t &var, int32_t val) {
__sync_synchronize();
var = val;
}
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
/*
* Unknown Platform. Use out-of-line functions, which in turn use mutexes.
* Slow but correct.
*/
#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.
*
*************************************************************************************************/
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;
}
/*
* TODO: Replace all uses of UMTX_CHECK and surrounding code
* with SimpleSingleton or TriStateSingleton, and remove UMTX_CHECK.
*/
if (umtx_initImplPreInit(uio)) {
(obj->*fp)();
umtx_initImplPostInit(uio, TRUE);
}
}
/*
* 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.
*
* For example:
*
* 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);
* }
*
* 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.
*/
// 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 */
/*************************************************************************************************
*
* Mutex Definitions. Platform Dependent, #if platform chain follows.
* TODO: Add a C++11 version.
* Need to convert all mutex using files to C++ first.
*
*************************************************************************************************/
#if U_PLATFORM_HAS_WIN32_API
/* 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.
/* Windows Definitions.
* Windows comes first in the platform chain.
* Cygwin (and possibly others) have both WIN32 and POSIX APIs. Prefer Win32 in this case.
*/
typedef struct U_INIT_ONCE {
long fState;
void *fContext;
} U_INIT_ONCE;
#define U_INIT_ONCE_STATIC_INIT {0, NULL}
/* For CRITICAL_SECTION */
/*
* 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.
*/
# 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);
U_INTERNAL 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 *);
#endif /*_CMUTEX*/
#endif /* UMUTEX_H */
/*eof*/

View file

@ -1,7 +1,7 @@
/*
******************************************************************************
*
* Copyright (C) 1999-2011, International Business Machines
* Copyright (C) 1999-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
@ -20,6 +20,7 @@
#include "unicode/udata.h"
#include "unicode/utf.h"
#include "unicode/utf16.h"
#include "uassert.h"
#include "ustr_imp.h"
#include "umutex.h"
#include "cmemory.h"
@ -102,7 +103,7 @@ typedef struct {
static UDataMemory *uCharNamesData=NULL;
static UCharNames *uCharNames=NULL;
static UErrorCode gLoadErrorCode=U_ZERO_ERROR;
static UInitOnce gCharNamesInitOnce = U_INITONCE_INITIALIZER;
/*
* Maximum length of character names (regular & 1.0).
@ -168,6 +169,7 @@ static UBool U_CALLCONV unames_cleanup(void)
if(uCharNames) {
uCharNames = NULL;
}
gCharNamesInitOnce.reset();
gMaxNameLength=0;
return TRUE;
}
@ -187,52 +189,25 @@ isAcceptable(void * /*context*/,
pInfo->formatVersion[0]==1);
}
static void U_CALLCONV
loadCharNames(UErrorCode &status) {
U_ASSERT(uCharNamesData == NULL);
U_ASSERT(uCharNames == NULL);
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);
}
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;
}
names=(UCharNames *)udata_getMemory(data);
/* 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;
umtx_initOnce(gCharNamesInitOnce, &loadCharNames, *pErrorCode);
return U_SUCCESS(*pErrorCode);
}
#define WRITE_CHAR(buffer, bufferLength, bufferPos, c) { \

View file

@ -43,6 +43,9 @@
U_NAMESPACE_BEGIN
// Forward Declarations
void U_CALLCONV locale_available_init();
/**
* A <code>Locale</code> object represents a specific geographical, political,
* or cultural region. An operation that requires a <code>Locale</code> to perform
@ -738,6 +741,8 @@ private:
* @internal
*/
friend Locale *locale_set_default_internal(const char *, UErrorCode& status);
friend void locale_available_init();
};
inline UBool

View file

@ -1,7 +1,7 @@
/*
******************************************************************************
*
* Copyright (C) 1996-2011, International Business Machines Corporation
* Copyright (C) 1996-2013, International Business Machines Corporation
* and others. All Rights Reserved.
*
******************************************************************************
@ -484,7 +484,6 @@ private:
UResourceBundle *fResource;
void constructForLocale(const UnicodeString& path, const Locale& locale, UErrorCode& error);
Locale *fLocale;
};
U_NAMESPACE_END

View file

@ -1,4 +1,4 @@
// Copyright (C) 2009-2012, International Business Machines
// Copyright (C) 2009-2013, International Business Machines
// Corporation and others. All Rights Reserved.
//
// Copyright 2001 and onwards Google Inc.
@ -183,7 +183,7 @@ class U_COMMON_API StringPiece : public UMemory {
* Maximum integer, used as a default value for substring methods.
* @stable ICU 4.2
*/
static const int32_t npos = 0x7fffffff;
static const int32_t npos; // = 0x7fffffff;
/**
* Returns a substring of this StringPiece.

View file

@ -1,6 +1,6 @@
/*
******************************************************************************
* Copyright (C) 2001-2012, International Business Machines
* Copyright (C) 2001-2013, International Business Machines
* Corporation and others. All Rights Reserved.
******************************************************************************
* file name: uclean.h
@ -100,101 +100,6 @@ U_STABLE void U_EXPORT2
u_cleanup(void);
/**
* 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
* @system
*/
typedef void *UMTX;
/**
* Function Pointer type for a user supplied mutex initialization function.
* The user-supplied function will be called by ICU whenever ICU needs to create a
* new mutex. The function implementation should create a mutex, and store a pointer
* to something that uniquely identifies the mutex into the UMTX that is supplied
* as a paramter.
* @param context user supplied value, obtained from from u_setMutexFunctions().
* @param mutex Receives a pointer that identifies the new mutex.
* The mutex init function must set the UMTX to a non-null value.
* Subsequent calls by ICU to lock, unlock, or destroy a mutex will
* 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
* @system
*/
typedef void U_CALLCONV UMtxInitFn (const void *context, UMTX *mutex, UErrorCode* status);
/**
* Function Pointer type for a user supplied mutex functions.
* One of the user-supplied functions with this signature will be called by ICU
* 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
* @system
*/
typedef void U_CALLCONV UMtxFn (const void *context, UMTX *mutex);
/**
* Set the functions that ICU will use for mutex operations
* Use of this function is optional; by default (without this function), ICU will
* directly access system functions for mutex operations
* 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 user-supplied mutex functions each time they
* are called.
* @param init Pointer to a mutex initialization function. Must be non-null.
* @param destroy Pointer to the mutex destroy function. Must be non-null.
* @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
* @system
*/
U_STABLE void U_EXPORT2
u_setMutexFunctions(const void *context, UMtxInitFn *init, UMtxFn *destroy, UMtxFn *lock, UMtxFn *unlock,
UErrorCode *status);
/**
* Pointer type for a user supplied atomic increment or decrement function.
* @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
* @system
*/
typedef int32_t U_CALLCONV UMtxAtomicFn(const void *context, int32_t *p);
/**
* Set the functions that ICU will use for atomic increment and decrement of int32_t values.
* Use of this function is optional; by default (without this function), ICU will
* use its own internal implementation of atomic increment/decrement.
* 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 increment and decrement functions each time they
* are called. This function can only be called
* @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
* @system
*/
U_STABLE 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().
@ -244,6 +149,108 @@ typedef void U_CALLCONV UMemFreeFn (const void *context, void *mem);
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.
* @deprecated ICU 52. This type is no longer supported.
* @system
*/
typedef void *UMTX;
/**
* Function Pointer type for a user supplied mutex initialization function.
* The user-supplied function will be called by ICU whenever ICU needs to create a
* new mutex. The function implementation should create a mutex, and store a pointer
* to something that uniquely identifies the mutex into the UMTX that is supplied
* as a paramter.
* @param context user supplied value, obtained from from u_setMutexFunctions().
* @param mutex Receives a pointer that identifies the new mutex.
* The mutex init function must set the UMTX to a non-null value.
* Subsequent calls by ICU to lock, unlock, or destroy a mutex will
* identify the mutex by the UMTX value.
* @param status Error status. Report errors back to ICU by setting this variable
* with an error code.
* @deprecated ICU 52. This function is no longer supported.
* @system
*/
typedef void U_CALLCONV UMtxInitFn (const void *context, UMTX *mutex, UErrorCode* status);
/**
* Function Pointer type for a user supplied mutex functions.
* One of the user-supplied functions with this signature will be called by ICU
* 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.
* @deprecated ICU 52. This function is no longer supported.
* @system
*/
typedef void U_CALLCONV UMtxFn (const void *context, UMTX *mutex);
/**
* Set the functions that ICU will use for mutex operations
* Use of this function is optional; by default (without this function), ICU will
* directly access system functions for mutex operations
* 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 user-supplied mutex functions each time they
* are called.
* @param init Pointer to a mutex initialization function. Must be non-null.
* @param destroy Pointer to the mutex destroy function. Must be non-null.
* @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.
* @deprecated ICU 52. This function is no longer supported.
* @system
*/
U_DEPRECATED void U_EXPORT2
u_setMutexFunctions(const void *context, UMtxInitFn *init, UMtxFn *destroy, UMtxFn *lock, UMtxFn *unlock,
UErrorCode *status);
/**
* Pointer type for a user supplied atomic increment or decrement function.
* @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.
* @deprecated ICU 52. This function is no longer supported.
* @system
*/
typedef int32_t U_CALLCONV UMtxAtomicFn(const void *context, int32_t *p);
/**
* Set the functions that ICU will use for atomic increment and decrement of int32_t values.
* Use of this function is optional; by default (without this function), ICU will
* use its own internal implementation of atomic increment/decrement.
* 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 increment and decrement functions each time they
* are called. This function can only be called
* @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.
* @deprecated ICU 52. This function is no longer supported.
* @system
*/
U_DEPRECATED void U_EXPORT2
u_setAtomicIncDecFunctions(const void *context, UMtxAtomicFn *inc, UMtxAtomicFn *dec,
UErrorCode *status);
#endif /* U_HIDE_SYSTEM_API */
#endif

View file

@ -1,6 +1,6 @@
/*
***************************************************************************
* Copyright (C) 1999-2011, International Business Machines Corporation
* Copyright (C) 1999-2013, International Business Machines Corporation
* and others. All Rights Reserved.
***************************************************************************
* Date Name Description
@ -22,6 +22,9 @@
U_NAMESPACE_BEGIN
// Forward Declarations.
void UnicodeSet_initInclusion(int32_t src, UErrorCode &status);
class BMPSet;
class ParsePosition;
class RBBIRuleScanner;
@ -1586,6 +1589,7 @@ private:
UnicodeString& rebuiltPat,
UErrorCode& ec);
friend void UnicodeSet_initInclusion(int32_t src, UErrorCode &status);
static const UnicodeSet* getInclusions(int32_t src, UErrorCode &status);
/**

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
*
* Copyright (C) 1999-2012, International Business Machines
* Copyright (C) 1999-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -127,7 +127,11 @@ private:
U_CDECL_BEGIN
static UnicodeSet *INCLUSIONS[UPROPS_SRC_COUNT] = { NULL }; // cached getInclusions()
struct Inclusion {
UnicodeSet *fSet;
UInitOnce fInitOnce;
};
static Inclusion gInclusions[UPROPS_SRC_COUNT]; // cached getInclusions()
STATIC_SIMPLE_SINGLETON(uni32Singleton);
@ -156,14 +160,13 @@ _set_addString(USet *set, const UChar *str, int32_t length) {
* Cleanup function for UnicodeSet
*/
static UBool U_CALLCONV uset_cleanup(void) {
int32_t i;
for(i = UPROPS_SRC_NONE; i < UPROPS_SRC_COUNT; ++i) {
if (INCLUSIONS[i] != NULL) {
delete INCLUSIONS[i];
INCLUSIONS[i] = NULL;
}
for(int32_t i = UPROPS_SRC_NONE; i < UPROPS_SRC_COUNT; ++i) {
Inclusion &in = gInclusions[i];
delete in.fSet;
in.fSet = NULL;
in.fInitOnce.reset();
}
UnicodeSetSingleton(uni32Singleton, NULL).deleteInstance();
return TRUE;
}
@ -173,105 +176,114 @@ U_CDECL_END
U_NAMESPACE_BEGIN
/*
Reduce excessive reallocation, and make it easier to detect initialization
problems.
Reduce excessive reallocation, and make it easier to detect initialization problems.
Usually you don't see smaller sets than this for Unicode 5.0.
*/
#define DEFAULT_INCLUSION_CAPACITY 3072
const UnicodeSet* UnicodeSet::getInclusions(int32_t src, UErrorCode &status) {
UBool needInit;
UMTX_CHECK(NULL, (INCLUSIONS[src] == NULL), needInit);
if (needInit) {
UnicodeSet* incl = new UnicodeSet();
USetAdder sa = {
(USet *)incl,
_set_add,
_set_addRange,
_set_addString,
NULL, // don't need remove()
NULL // don't need removeRange()
};
if (incl != NULL) {
incl->ensureCapacity(DEFAULT_INCLUSION_CAPACITY, status);
switch(src) {
case UPROPS_SRC_CHAR:
uchar_addPropertyStarts(&sa, &status);
break;
case UPROPS_SRC_PROPSVEC:
upropsvec_addPropertyStarts(&sa, &status);
break;
case UPROPS_SRC_CHAR_AND_PROPSVEC:
uchar_addPropertyStarts(&sa, &status);
upropsvec_addPropertyStarts(&sa, &status);
break;
#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;
}
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;
}
return INCLUSIONS[src];
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_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 *

View file

@ -1,6 +1,6 @@
/*
******************************************************************************
* Copyright (C) 1999-2012, International Business Machines Corporation and
* Copyright (C) 1999-2013, International Business Machines Corporation and
* others. All Rights Reserved.
******************************************************************************
*
@ -118,11 +118,11 @@ operator+ (const UnicodeString &s1, const UnicodeString &s2) {
void
UnicodeString::addRef()
{ umtx_atomic_inc((int32_t *)fUnion.fFields.fArray - 1);}
{ umtx_atomic_inc((atomic_int32_t *)fUnion.fFields.fArray - 1);}
int32_t
UnicodeString::removeRef()
{ return umtx_atomic_dec((int32_t *)fUnion.fFields.fArray - 1);}
{ return umtx_atomic_dec((atomic_int32_t *)fUnion.fFields.fArray - 1);}
int32_t
UnicodeString::refCount() const
@ -1679,13 +1679,16 @@ UnicodeString::cloneArrayIfNeeded(int32_t newCapacity,
// release the old array
if(flags & kRefCounted) {
// the array is refCounted; decrement and release if 0
int32_t *pRefCount = ((int32_t *)oldArray - 1);
atomic_int32_t *pRefCount = ((atomic_int32_t *)oldArray - 1);
if(umtx_atomic_dec(pRefCount) == 0) {
if(pBufferToDelete == 0) {
uprv_free(pRefCount);
// Note: cast to (void *) is needed with MSVC, where atomic_int32_t
// is defined as volatile. (Volatile has useful non-standard behavior
// with this compiler.)
uprv_free((void *)pRefCount);
} else {
// the caller requested to delete it himself
*pBufferToDelete = pRefCount;
*pBufferToDelete = (int32_t *)pRefCount;
}
}
}

View file

@ -34,6 +34,7 @@
#include "ulocimp.h"
#include "umutex.h"
#include "putilimp.h"
#include "uassert.h"
/*
@ -42,6 +43,7 @@ TODO: This cache should probably be removed when the deprecated code is
completely removed.
*/
static UHashtable *cache = NULL;
static UInitOnce gCacheInitOnce;
static UMutex resbMutex = U_MUTEX_INITIALIZER;
@ -261,29 +263,19 @@ static UBool U_CALLCONV ures_cleanup(void)
cache = NULL;
}
}
gCacheInitOnce.reset();
return (cache == NULL);
}
/** INTERNAL: Initializes the cache for resources */
static void createCache(UErrorCode &status) {
U_ASSERT(cache == NULL);
cache = uhash_open(hashEntry, compareEntries, NULL, &status);
ucln_common_registerCleanup(UCLN_COMMON_URES, ures_cleanup);
}
static void initCache(UErrorCode *status) {
UBool makeCache = FALSE;
UMTX_CHECK(&resbMutex, (cache == NULL), makeCache);
if(makeCache) {
UHashtable *newCache = uhash_open(hashEntry, compareEntries, NULL, status);
if (U_FAILURE(*status)) {
return;
}
umtx_lock(&resbMutex);
if(cache == NULL) {
cache = newCache;
newCache = NULL;
ucln_common_registerCleanup(UCLN_COMMON_URES, ures_cleanup);
}
umtx_unlock(&resbMutex);
if(newCache != NULL) {
uhash_close(newCache);
}
}
umtx_initOnce(gCacheInitOnce, &createCache, *status);
}
/** INTERNAL: sets the name (locale) of the resource bundle to given name */

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
*
* Copyright (C) 2003-2012, International Business Machines
* Copyright (C) 2003-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -42,6 +42,7 @@ U_CDECL_BEGIN
Static cache for already opened StringPrep profiles
*/
static UHashtable *SHARED_DATA_HASHTABLE = NULL;
static UInitOnce gSharedDataInitOnce;
static UMutex usprepMutex = U_MUTEX_INITIALIZER;
@ -195,32 +196,25 @@ static UBool U_CALLCONV usprep_cleanup(void){
SHARED_DATA_HASHTABLE = NULL;
}
}
gSharedDataInitOnce.reset();
return (SHARED_DATA_HASHTABLE == NULL);
}
U_CDECL_END
/** Initializes the cache for resources */
static void U_CALLCONV
createCache(UErrorCode &status) {
SHARED_DATA_HASHTABLE = uhash_open(hashEntry, compareEntries, NULL, &status);
if (U_FAILURE(status)) {
SHARED_DATA_HASHTABLE = NULL;
}
ucln_common_registerCleanup(UCLN_COMMON_USPREP, usprep_cleanup);
}
static void
initCache(UErrorCode *status) {
UBool makeCache;
UMTX_CHECK(&usprepMutex, (SHARED_DATA_HASHTABLE == NULL), makeCache);
if(makeCache) {
UHashtable *newCache = uhash_open(hashEntry, compareEntries, NULL, status);
if (U_SUCCESS(*status)) {
umtx_lock(&usprepMutex);
if(SHARED_DATA_HASHTABLE == NULL) {
SHARED_DATA_HASHTABLE = newCache;
ucln_common_registerCleanup(UCLN_COMMON_USPREP, usprep_cleanup);
newCache = NULL;
}
umtx_unlock(&usprepMutex);
}
if(newCache != NULL) {
uhash_close(newCache);
}
}
umtx_initOnce(gSharedDataInitOnce, &createCache, *status);
}
static UBool U_CALLCONV

View file

@ -1,7 +1,7 @@
/*
******************************************************************************
*
* Copyright (C) 2001-2011, International Business Machines
* Copyright (C) 2001-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
@ -735,9 +735,7 @@ uint16_t ForwardUTrie2StringIterator::next16() {
UTrie2 *UTrie2Singleton::getInstance(InstantiatorFn *instantiator, const void *context,
UErrorCode &errorCode) {
void *duplicate;
UTrie2 *instance=(UTrie2 *)singleton.getInstance(instantiator, context, duplicate, errorCode);
utrie2_close((UTrie2 *)duplicate);
UTrie2 *instance=(UTrie2 *)singleton.getInstance(instantiator, context, errorCode);
return instance;
}

View file

@ -1,11 +1,11 @@
## -*-makefile-*-
## Linux-specific setup
## Copyright (c) 1999-2012, International Business Machines Corporation and
## Copyright (c) 1999-2013, International Business Machines Corporation and
## others. All Rights Reserved.
## Commands to generate dependency files
GEN_DEPS.c= $(CC) -E -MM $(DEFS) $(CPPFLAGS)
GEN_DEPS.cc= $(CXX) -E -MM $(DEFS) $(CPPFLAGS)
GEN_DEPS.cc= $(CXX) -E -MM $(DEFS) $(CPPFLAGS) $(CXXFLAGS)
## Flags for position independent code
SHAREDLIBCFLAGS = -fPIC

View file

@ -91,7 +91,7 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x86\Release/icuio.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
@ -133,7 +133,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x86\Debug/icuio.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
@ -176,7 +176,7 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Release/icuio.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
@ -216,7 +216,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Debug/icuio.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
*
* Copyright (C) 1998-2012, International Business Machines
* Copyright (C) 1998-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -25,6 +25,7 @@
#include "cmemory.h"
#include "cstring.h"
#include "ucln_io.h"
#include "mutex.h"
#include "umutex.h"
#include "unicode/ustring.h"
#include "unicode/uloc.h"
@ -42,27 +43,24 @@ static UBool U_CALLCONV locbund_cleanup(void) {
}
U_CDECL_END
static UMutex gLock = U_MUTEX_INITIALIZER;
static inline UNumberFormat * copyInvariantFormatter(ULocaleBundle *result, UNumberFormatStyle style) {
U_NAMESPACE_USE
Mutex lock(&gLock);
if (result->fNumberFormat[style-1] == NULL) {
UErrorCode status = U_ZERO_ERROR;
UBool needsInit;
UMTX_CHECK(NULL, gPosixNumberFormat[style-1] == NULL, needsInit);
if (needsInit) {
if (gPosixNumberFormat[style-1] == NULL) {
UErrorCode status = U_ZERO_ERROR;
UNumberFormat *formatAlias = unum_open(style, NULL, 0, "en_US_POSIX", NULL, &status);
/* Cache upon first request. */
if (U_SUCCESS(status)) {
umtx_lock(NULL);
gPosixNumberFormat[style-1] = formatAlias;
ucln_io_registerCleanup(UCLN_IO_LOCBUND, locbund_cleanup);
umtx_unlock(NULL);
}
}
/* Copy the needed formatter. */
result->fNumberFormat[style-1] = unum_clone(gPosixNumberFormat[style-1], &status);
if (gPosixNumberFormat[style-1] != NULL) {
UErrorCode status = U_ZERO_ERROR;
result->fNumberFormat[style-1] = unum_clone(gPosixNumberFormat[style-1], &status);
}
}
return result->fNumberFormat[style-1];
}

View file

@ -1,260 +1,264 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F7659D77-09CF-4FE9-ACEE-927287AA9509}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\x86\Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\x86\Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\x86\Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\x86\Debug\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\x64\Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\x64\Debug\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<TypeLibraryName>.\x86\Release/cal.tlb</TypeLibraryName>
</Midl>
<ClCompile>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\x86\Release/cal.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
<ObjectFileName>.\x86\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\x86\Release/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>icuuc.lib;icuin.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\x86\Release/cal.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>../../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>.\x86\Release/cal.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
<TypeLibraryName>.\x64\Release/cal.tlb</TypeLibraryName>
</Midl>
<ClCompile>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\x64\Release/cal.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
<ObjectFileName>.\x64\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\x64\Release/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>icuuc.lib;icuin.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\x64\Release/cal.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>../../../lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>.\x64\Release/cal.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<TypeLibraryName>.\x86\Debug/cal.tlb</TypeLibraryName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\x86\Debug/cal.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
<ObjectFileName>.\x86\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\x86\Debug/</ProgramDataBaseFileName>
<BrowseInformation>true</BrowseInformation>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>icuucd.lib;icuind.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\x86\Debug/cal.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>../../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\x86\Debug/cal.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
<TypeLibraryName>.\x64\Debug/cal.tlb</TypeLibraryName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\x64\Debug/cal.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>
<ObjectFileName>.\x64\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\x64\Debug/</ProgramDataBaseFileName>
<BrowseInformation>true</BrowseInformation>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>icuucd.lib;icuind.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\x64\Debug/cal.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>../../../lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\x64\Debug/cal.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="cal.c" />
<ClCompile Include="uprint.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="uprint.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\common\common.vcxproj">
<Project>{73c0a65b-d1f2-4de1-b3a6-15dad2c23f3d}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="..\..\i18n\i18n.vcxproj">
<Project>{0178b127-6269-407d-b112-93877bb62776}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F7659D77-09CF-4FE9-ACEE-927287AA9509}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\x86\Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\x86\Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\x86\Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\x86\Debug\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\x64\Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\x64\Debug\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<TypeLibraryName>.\x86\Release/cal.tlb</TypeLibraryName>
</Midl>
<ClCompile>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\x86\Release/cal.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
<ObjectFileName>.\x86\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\x86\Release/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>icuuc.lib;icuin.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\x86\Release/cal.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>../../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>.\x86\Release/cal.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
<TypeLibraryName>.\x64\Release/cal.tlb</TypeLibraryName>
</Midl>
<ClCompile>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\x64\Release/cal.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
<ObjectFileName>.\x64\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\x64\Release/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>icuuc.lib;icuin.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\x64\Release/cal.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>../../../lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>.\x64\Release/cal.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<TypeLibraryName>.\x86\Debug/cal.tlb</TypeLibraryName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\x86\Debug/cal.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
<ObjectFileName>.\x86\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\x86\Debug/</ProgramDataBaseFileName>
<BrowseInformation>true</BrowseInformation>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>icuucd.lib;icuind.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\x86\Debug/cal.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>../../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\x86\Debug/cal.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
<TypeLibraryName>.\x64\Debug/cal.tlb</TypeLibraryName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\x64\Debug/cal.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>
<ObjectFileName>.\x64\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\x64\Debug/</ProgramDataBaseFileName>
<BrowseInformation>true</BrowseInformation>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>icuucd.lib;icuind.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>.\x64\Debug/cal.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>../../../lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\x64\Debug/cal.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="cal.c">
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="uprint.c">
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="uprint.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\common\common.vcxproj">
<Project>{73c0a65b-d1f2-4de1-b3a6-15dad2c23f3d}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="..\..\i18n\i18n.vcxproj">
<Project>{0178b127-6269-407d-b112-93877bb62776}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2012, International Business Machines Corporation and
* Copyright (c) 1997-2013, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
/********************************************************************************
@ -234,10 +234,6 @@ int main(int argc, const char* const argv[])
} /* End of loop that repeats the entire test, if requested. (Normally doesn't loop) */
if (ALLOCATION_COUNT > 0) {
fprintf(stderr, "There were %d blocks leaked!\n", ALLOCATION_COUNT);
nerrors++;
}
endTime = uprv_getRawUTCtime();
diffTime = (int32_t)(endTime - startTime);
printf("Elapsed Time: %02d:%02d:%02d.%03d\n",

View file

@ -88,7 +88,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x86\Debug/cintltst.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
@ -127,7 +127,7 @@
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x86\Release/cintltst.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
@ -164,7 +164,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Debug/cintltst.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>
@ -202,7 +202,7 @@
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Release/cintltst.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
@ -270,10 +270,6 @@
<ClCompile Include="ucnvseltst.c" />
<ClCompile Include="ucsdetst.c" />
<ClCompile Include="udatatst.c">
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="ccaltst.c" />
<ClCompile Include="cdateintervalformattest.c" />

View file

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 2003-2009, International Business Machines Corporation and
* Copyright (c) 2003-2013, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
/*
@ -29,8 +29,6 @@ typedef union {
} ctest_AlignedMemory;
static void TestHeapFunctions(void);
static void TestMutexFunctions(void);
static void TestIncDecFunctions(void);
void addHeapMutexTest(TestNode **root);
@ -39,8 +37,6 @@ void
addHeapMutexTest(TestNode** root)
{
addTest(root, &TestHeapFunctions, "hpmufn/TestHeapFunctions" );
addTest(root, &TestMutexFunctions, "hpmufn/TestMutexFunctions" );
addTest(root, &TestIncDecFunctions, "hpmufn/TestIncDecFunctions");
}
static int32_t gMutexFailures = 0;
@ -203,273 +199,3 @@ static void TestHeapFunctions() {
}
/*
* Test u_setMutexFunctions()
*/
int gTotalMutexesInitialized = 0; /* Total number of mutexes created */
int gTotalMutexesActive = 0; /* Total mutexes created, but not destroyed */
int gAccumulatedLocks = 0;
const void *gMutexContext;
typedef struct DummyMutex {
int fLockCount;
int fMagic;
} DummyMutex;
static void U_CALLCONV myMutexInit(const void *context, UMTX *mutex, UErrorCode *status) {
DummyMutex *theMutex;
TEST_STATUS(*status, U_ZERO_ERROR);
theMutex = (DummyMutex *)malloc(sizeof(DummyMutex));
theMutex->fLockCount = 0;
theMutex->fMagic = 123456;
gTotalMutexesInitialized++;
gTotalMutexesActive++;
gMutexContext = context;
*mutex = theMutex;
}
static void U_CALLCONV myMutexDestroy(const void *context, UMTX *mutex) {
DummyMutex *This = *(DummyMutex **)mutex;
gTotalMutexesActive--;
TEST_ASSERT(This->fLockCount == 0);
TEST_ASSERT(This->fMagic == 123456);
This->fMagic = 0;
This->fLockCount = 0;
free(This);
}
static void U_CALLCONV myMutexLock(const void *context, UMTX *mutex) {
DummyMutex *This = *(DummyMutex **)mutex;
TEST_ASSERT(This->fMagic == 123456);
This->fLockCount++;
gAccumulatedLocks++;
}
static void U_CALLCONV myMutexUnlock(const void *context, UMTX *mutex) {
DummyMutex *This = *(DummyMutex **)mutex;
TEST_ASSERT(This->fMagic == 123456);
This->fLockCount--;
TEST_ASSERT(This->fLockCount >= 0);
}
static void TestMutexFunctions() {
UErrorCode status = U_ZERO_ERROR;
UResourceBundle *rb = NULL;
char *icuDataDir;
gMutexFailures = 0;
/* Save initial ICU state so that it can be restored later.
* u_cleanup(), which is called in this test, resets ICU's state.
*/
icuDataDir = safeGetICUDataDirectory();
/* Verify that ICU can be cleaned up and reinitialized successfully.
* Failure here usually means that some ICU service didn't clean up successfully,
* probably because some earlier test accidently left something open. */
ctest_resetICU();
/* Can not set mutex functions if ICU is already initialized */
u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, myMutexUnlock, &status);
TEST_STATUS(status, U_INVALID_STATE_ERROR);
/* Un-initialize ICU */
u_cleanup();
/* Can not set Mutex functions with NULL values */
status = U_ZERO_ERROR;
u_setMutexFunctions(&gContext, NULL, myMutexDestroy, myMutexLock, myMutexUnlock, &status);
TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
status = U_ZERO_ERROR;
u_setMutexFunctions(&gContext, myMutexInit, NULL, myMutexLock, myMutexUnlock, &status);
TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
status = U_ZERO_ERROR;
u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, NULL, myMutexUnlock, &status);
TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
status = U_ZERO_ERROR;
u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, NULL, &status);
TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
/* u_setMutexFunctions() should work with null or non-null context pointer */
status = U_ZERO_ERROR;
u_setMutexFunctions(NULL, myMutexInit, myMutexDestroy, myMutexLock, myMutexUnlock, &status);
TEST_STATUS(status, U_ZERO_ERROR);
u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, myMutexUnlock, &status);
TEST_STATUS(status, U_ZERO_ERROR);
/* After reinitializing ICU, we should not be able to set the mutex funcs again. */
status = U_ZERO_ERROR;
u_setDataDirectory(icuDataDir);
u_init(&status);
TEST_STATUS(status, U_ZERO_ERROR);
u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, myMutexUnlock, &status);
TEST_STATUS(status, U_INVALID_STATE_ERROR);
/* Doing ICU operations should cause allocations to come through our test mutexes */
gBlockCount = 0;
status = U_ZERO_ERROR;
/*
* Note: If we get assertion failures here because
* uresbund.c:resbMutex's fMagic is wrong, check if ures_flushCache() did
* flush and delete the cache. If it fails to empty the cache, it will not
* delete it and ures_cleanup() will not destroy resbMutex.
* That would leave a mutex from the default implementation which does not
* pass this test implementation's assertions.
*/
rb = ures_open(NULL, "es", &status);
TEST_STATUS(status, U_ZERO_ERROR);
TEST_ASSERT(gTotalMutexesInitialized > 0);
TEST_ASSERT(gTotalMutexesActive > 0);
ures_close(rb);
/* Cleanup should destroy all of the mutexes. */
ctest_resetICU();
status = U_ZERO_ERROR;
TEST_ASSERT(gTotalMutexesInitialized > 0);
TEST_ASSERT(gTotalMutexesActive == 0);
/* Additional ICU operations should no longer use our dummy test mutexes */
gTotalMutexesInitialized = 0;
gTotalMutexesActive = 0;
u_init(&status);
TEST_STATUS(status, U_ZERO_ERROR);
status = U_ZERO_ERROR;
rb = ures_open(NULL, "fr", &status);
TEST_STATUS(status, U_ZERO_ERROR);
TEST_ASSERT(gTotalMutexesInitialized == 0);
TEST_ASSERT(gTotalMutexesActive == 0);
ures_close(rb);
free(icuDataDir);
if(gMutexFailures) {
log_info("Note: these failures may be caused by ICU failing to initialize/uninitialize properly.\n");
log_verbose("Check for prior tests which may not have closed all open resources. See the internal function ures_flushCache()\n");
}
}
/*
* Test Atomic Increment & Decrement Functions
*/
int gIncCount = 0;
int gDecCount = 0;
const void *gIncDecContext;
const void *gExpectedContext = &gIncDecContext;
static int32_t U_CALLCONV myIncFunc(const void *context, int32_t *p) {
int32_t retVal;
TEST_ASSERT(context == gExpectedContext);
gIncCount++;
retVal = ++(*p);
return retVal;
}
static int32_t U_CALLCONV myDecFunc(const void *context, int32_t *p) {
int32_t retVal;
TEST_ASSERT(context == gExpectedContext);
gDecCount++;
retVal = --(*p);
return retVal;
}
static void TestIncDecFunctions() {
UErrorCode status = U_ZERO_ERROR;
int32_t t = 1; /* random value to make sure that Inc/dec works */
char *dataDir;
/* Save ICU's data dir and tracing functions so that they can be resored
after cleanup and reinit. */
dataDir = safeGetICUDataDirectory();
/* Verify that ICU can be cleaned up and reinitialized successfully.
* Failure here usually means that some ICU service didn't clean up successfully,
* probably because some earlier test accidently left something open. */
ctest_resetICU();
/* Can not set mutex functions if ICU is already initialized */
u_setAtomicIncDecFunctions(&gIncDecContext, myIncFunc, myDecFunc, &status);
TEST_STATUS(status, U_INVALID_STATE_ERROR);
/* Clean up ICU */
u_cleanup();
/* Can not set functions with NULL values */
status = U_ZERO_ERROR;
u_setAtomicIncDecFunctions(&gIncDecContext, NULL, myDecFunc, &status);
TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
status = U_ZERO_ERROR;
u_setAtomicIncDecFunctions(&gIncDecContext, myIncFunc, NULL, &status);
TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
/* u_setIncDecFunctions() should work with null or non-null context pointer */
status = U_ZERO_ERROR;
gExpectedContext = NULL;
u_setAtomicIncDecFunctions(NULL, myIncFunc, myDecFunc, &status);
TEST_STATUS(status, U_ZERO_ERROR);
gExpectedContext = &gIncDecContext;
u_setAtomicIncDecFunctions(&gIncDecContext, myIncFunc, myDecFunc, &status);
TEST_STATUS(status, U_ZERO_ERROR);
/* After reinitializing ICU, we should not be able to set the inc/dec funcs again. */
status = U_ZERO_ERROR;
u_setDataDirectory(dataDir);
u_init(&status);
TEST_STATUS(status, U_ZERO_ERROR);
gExpectedContext = &gIncDecContext;
u_setAtomicIncDecFunctions(&gIncDecContext, myIncFunc, myDecFunc, &status);
TEST_STATUS(status, U_INVALID_STATE_ERROR);
/* Doing ICU operations should cause our functions to be called */
gIncCount = 0;
gDecCount = 0;
umtx_atomic_inc(&t);
TEST_ASSERT(t == 2);
umtx_atomic_dec(&t);
TEST_ASSERT(t == 1);
TEST_ASSERT(gIncCount > 0);
TEST_ASSERT(gDecCount > 0);
/* Cleanup should cancel use of our inc/dec functions. */
/* Additional ICU operations should not use them */
ctest_resetICU();
gIncCount = 0;
gDecCount = 0;
status = U_ZERO_ERROR;
u_setDataDirectory(dataDir);
u_init(&status);
TEST_ASSERT(gIncCount == 0);
TEST_ASSERT(gDecCount == 0);
status = U_ZERO_ERROR;
umtx_atomic_inc(&t);
umtx_atomic_dec(&t);
TEST_STATUS(status, U_ZERO_ERROR);
TEST_ASSERT(gIncCount == 0);
TEST_ASSERT(gDecCount == 0);
free(dataDir);
}

View file

@ -228,7 +228,9 @@
<ClCompile Include="regiontst.cpp" />
<ClCompile Include="ucharstrietest.cpp" />
<ClCompile Include="itrbbi.cpp" />
<ClCompile Include="rbbiapts.cpp" />
<ClCompile Include="rbbiapts.cpp">
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="rbbitst.cpp" />
<ClCompile Include="itspoof.cpp" />
<ClCompile Include="allcoll.cpp" />
@ -258,10 +260,7 @@
<ClCompile Include="uvectest.cpp" />
<ClCompile Include="v32test.cpp" />
<ClCompile Include="simplethread.cpp">
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="strtest.cpp">
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
@ -276,13 +275,17 @@
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="tsputil.cpp" />
<ClCompile Include="uobjtest.cpp" />
<ClCompile Include="uobjtest.cpp">
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="astrotst.cpp" />
<ClCompile Include="calcasts.cpp" />
<ClCompile Include="callimts.cpp" />
<ClCompile Include="calregts.cpp" />
<ClCompile Include="caltest.cpp" />
<ClCompile Include="caltztst.cpp" />
<ClCompile Include="caltztst.cpp">
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="compactdecimalformattest.cpp" />
<ClCompile Include="dadrcal.cpp" />
<ClCompile Include="dadrfmt.cpp" />
@ -322,11 +325,15 @@
<ClCompile Include="tsnmfmt.cpp" />
<ClCompile Include="tufmtts.cpp" />
<ClCompile Include="tzbdtest.cpp" />
<ClCompile Include="tzfmttst.cpp" />
<ClCompile Include="tzfmttst.cpp">
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="tzoffloc.cpp" />
<ClCompile Include="tzregts.cpp" />
<ClCompile Include="tzrulets.cpp" />
<ClCompile Include="tztest.cpp" />
<ClCompile Include="tztest.cpp">
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="windttst.cpp">
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
@ -343,33 +350,46 @@
<ClCompile Include="idnaref.cpp" />
<ClCompile Include="nptrans.cpp" />
<ClCompile Include="punyref.c" />
<ClCompile Include="testidn.cpp" />
<ClCompile Include="testidn.cpp">
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="testidna.cpp" />
<ClCompile Include="uts46test.cpp" />
<ClCompile Include="aliastst.cpp" />
<ClCompile Include="loctest.cpp" />
<ClCompile Include="restest.cpp" />
<ClCompile Include="restsnew.cpp" />
<ClCompile Include="intltest.cpp" />
<ClCompile Include="itmajor.cpp" />
<ClCompile Include="itutil.cpp" />
<ClCompile Include="intltest.cpp">
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="itmajor.cpp">
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="itutil.cpp">
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="testutil.cpp" />
<ClCompile Include="textfile.cpp" />
<ClCompile Include="tokiter.cpp" />
<ClCompile Include="winutil.cpp">
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="canittst.cpp" />
<ClCompile Include="normconf.cpp" />
<ClCompile Include="tstnorm.cpp" />
<ClCompile Include="tstnrapi.cpp" />
<ClCompile Include="ucdtest.cpp" />
<ClCompile Include="tstnorm.cpp">
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="tstnrapi.cpp">
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="ucdtest.cpp">
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="usettest.cpp" />
<ClCompile Include="regextst.cpp" />
<ClCompile Include="icusvtst.cpp" />
<ClCompile Include="icusvtst.cpp">
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="citrtest.cpp" />
<ClCompile Include="reptest.cpp" />
<ClCompile Include="sfwdchit.cpp" />
@ -541,4 +561,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View file

@ -15,7 +15,6 @@
#include "unicode/utrace.h"
#include "unicode/uclean.h"
#include "umutex.h"
#include "putilimp.h"
/* NOTES:
@ -122,7 +121,6 @@ int WARN_ON_MISSING_DATA = 0; /* Reduce data errs to warnings? */
UTraceLevel ICU_TRACE = UTRACE_OFF; /* ICU tracing level */
size_t MINIMUM_MEMORY_SIZE_FAILURE = (size_t)-1; /* Minimum library memory allocation window that will fail. */
size_t MAXIMUM_MEMORY_SIZE_FAILURE = (size_t)-1; /* Maximum library memory allocation window that will fail. */
int32_t ALLOCATION_COUNT = 0;
static const char *ARGV_0 = "[ALL]";
static const char *XML_FILE_NAME=NULL;
static char XML_PREFIX[256];
@ -874,7 +872,6 @@ static void *U_CALLCONV ctest_libMalloc(const void *context, size_t size) {
if (MINIMUM_MEMORY_SIZE_FAILURE <= size && size <= MAXIMUM_MEMORY_SIZE_FAILURE) {
return NULL;
}
umtx_atomic_inc(&ALLOCATION_COUNT);
return malloc(size);
}
static void *U_CALLCONV ctest_libRealloc(const void *context, void *mem, size_t size) {
@ -885,16 +882,9 @@ static void *U_CALLCONV ctest_libRealloc(const void *context, void *mem, size_t
/*free(mem);*/ /* Realloc doesn't free on failure. */
return NULL;
}
if (mem == NULL) {
/* New allocation. */
umtx_atomic_inc(&ALLOCATION_COUNT);
}
return realloc(mem, size);
}
static void U_CALLCONV ctest_libFree(const void *context, void *mem) {
if (mem != NULL) {
umtx_atomic_dec(&ALLOCATION_COUNT);
}
free(mem);
}

View file

@ -92,7 +92,7 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x86\Release/genbrk.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
@ -132,7 +132,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x86\Debug/genbrk.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
@ -175,7 +175,7 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Release/genbrk.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
@ -214,7 +214,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Debug/genbrk.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>

View file

@ -90,7 +90,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<PrecompiledHeader>
</PrecompiledHeader>
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
@ -120,7 +120,7 @@
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader>
</PrecompiledHeader>
@ -155,7 +155,7 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Release/gencfu.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
@ -193,7 +193,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Debug/gencfu.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>

View file

@ -92,7 +92,7 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x86\Release/gencnval.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
@ -132,7 +132,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x86\Debug/gencnval.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
@ -175,7 +175,7 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Release/gencnval.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
@ -214,7 +214,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Debug/gencnval.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>

View file

@ -87,7 +87,7 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x86\Release\gennorm2.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Release\</AssemblerListingLocation>
@ -131,7 +131,7 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x86\Debug\gennorm2.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Debug\</AssemblerListingLocation>
@ -172,7 +172,7 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Release\gennorm2.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Release\</AssemblerListingLocation>
@ -216,7 +216,7 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Debug\gennorm2.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Debug\</AssemblerListingLocation>

View file

@ -92,7 +92,7 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x86\Release/gensprep.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
@ -132,7 +132,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x86\Debug/gensprep.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
@ -174,7 +174,7 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Release/gensprep.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
@ -213,7 +213,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Debug/gensprep.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>

View file

@ -93,7 +93,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x86\Debug/makeconv.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
@ -134,7 +134,7 @@
<PreprocessorDefinitions>WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x86\Release/makeconv.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
@ -175,7 +175,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Debug/makeconv.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>
@ -215,7 +215,7 @@
<PreprocessorDefinitions>WIN64;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeaderOutputFile>.\x64\Release/makeconv.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>

View file

@ -266,7 +266,9 @@
<ClCompile Include="pkg_icu.cpp" />
<ClCompile Include="pkgitems.cpp" />
<ClCompile Include="ppucd.cpp" />
<ClCompile Include="swapimpl.cpp" />
<ClCompile Include="swapimpl.cpp">
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ClCompile Include="toolutil.cpp">
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>