+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
-* Copyright (C) 1997-2011, International Business Machines
+* Copyright (C) 1997-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
* file name: locavailable.cpp
-* encoding: US-ASCII
+* encoding: UTF-8
* tab size: 8 (not used)
* indentation:4
*
#include "unicode/ures.h"
#include "cmemory.h"
#include "ucln_cmn.h"
+#include "uassert.h"
#include "umutex.h"
#include "uresimp.h"
// C++ API ----------------------------------------------------------------- ***
+U_NAMESPACE_BEGIN
+
static icu::Locale* availableLocaleList = NULL;
static int32_t availableLocaleListCount;
+static icu::UInitOnce gInitOnce = U_INITONCE_INITIALIZER;
+
+U_NAMESPACE_END
U_CDECL_BEGIN
availableLocaleList = NULL;
}
availableLocaleListCount = 0;
+ gInitOnce.reset();
return TRUE;
}
U_NAMESPACE_BEGIN
+void U_CALLCONV locale_available_init() {
+ // This function is a friend of class Locale.
+ // This function is only invoked via umtx_initOnce().
+
+ // for now, there is a hardcoded list, so just walk through that list and set it up.
+ // Note: this function is a friend of class Locale.
+ availableLocaleListCount = uloc_countAvailable();
+ if(availableLocaleListCount) {
+ availableLocaleList = new Locale[availableLocaleListCount];
+ }
+ if (availableLocaleList == NULL) {
+ availableLocaleListCount= 0;
+ }
+ for (int32_t locCount=availableLocaleListCount-1; locCount>=0; --locCount) {
+ availableLocaleList[locCount].setFromPOSIXID(uloc_getAvailable(locCount));
+ }
+ ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE, locale_available_cleanup);
+}
+
const Locale* U_EXPORT2
Locale::getAvailableLocales(int32_t& count)
{
- // for now, there is a hardcoded list, so just walk through that list and set it up.
- UBool needInit;
- UMTX_CHECK(NULL, availableLocaleList == NULL, needInit);
-
- if (needInit) {
- int32_t locCount = uloc_countAvailable();
- Locale *newLocaleList = 0;
- if(locCount) {
- newLocaleList = new Locale[locCount];
- }
- if (newLocaleList == NULL) {
- count = 0;
- return NULL;
- }
-
- count = locCount;
-
- while(--locCount >= 0) {
- newLocaleList[locCount].setFromPOSIXID(uloc_getAvailable(locCount));
- }
-
- umtx_lock(NULL);
- if(availableLocaleList == 0) {
- availableLocaleListCount = count;
- availableLocaleList = newLocaleList;
- newLocaleList = NULL;
- ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE, locale_available_cleanup);
- }
- umtx_unlock(NULL);
- delete []newLocaleList;
- }
+ umtx_initOnce(gInitOnce, &locale_available_init);
count = availableLocaleListCount;
return availableLocaleList;
}
static char** _installedLocales = NULL;
static int32_t _installedLocalesCount = 0;
+static icu::UInitOnce _installedLocalesInitOnce;
/* ### Get available **************************************************/
_installedLocales = NULL;
_installedLocalesCount = 0;
+ _installedLocalesInitOnce.reset();
uprv_free(temp);
}
return TRUE;
}
-static void _load_installedLocales()
-{
- UBool localesLoaded;
+// Load Installed Locales. This function will be called exactly once
+// via the initOnce mechanism.
- UMTX_CHECK(NULL, _installedLocales != NULL, localesLoaded);
+static void U_CALLCONV loadInstalledLocales() {
+ UResourceBundle *indexLocale = NULL;
+ UResourceBundle installed;
+ UErrorCode status = U_ZERO_ERROR;
+ int32_t i = 0;
+ int32_t localeCount;
- if (localesLoaded == FALSE) {
- UResourceBundle *indexLocale = NULL;
- UResourceBundle installed;
- UErrorCode status = U_ZERO_ERROR;
- char ** temp;
- int32_t i = 0;
- int32_t localeCount;
-
- ures_initStackObject(&installed);
- indexLocale = ures_openDirect(NULL, _kIndexLocaleName, &status);
- ures_getByKey(indexLocale, _kIndexTag, &installed, &status);
-
- if(U_SUCCESS(status)) {
- localeCount = ures_getSize(&installed);
- temp = (char **) uprv_malloc(sizeof(char*) * (localeCount+1));
- /* Check for null pointer */
- if (temp != NULL) {
- ures_resetIterator(&installed);
- while(ures_hasNext(&installed)) {
- ures_getNextString(&installed, NULL, (const char **)&temp[i++], &status);
- }
- temp[i] = NULL;
-
- umtx_lock(NULL);
- if (_installedLocales == NULL)
- {
- _installedLocalesCount = localeCount;
- _installedLocales = temp;
- temp = NULL;
- ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
- }
- umtx_unlock(NULL);
-
- uprv_free(temp);
+ U_ASSERT(_installedLocales == NULL);
+ U_ASSERT(_installedLocalesCount == 0);
+
+ _installedLocalesCount = 0;
+ ures_initStackObject(&installed);
+ indexLocale = ures_openDirect(NULL, _kIndexLocaleName, &status);
+ ures_getByKey(indexLocale, _kIndexTag, &installed, &status);
+
+ if(U_SUCCESS(status)) {
+ localeCount = ures_getSize(&installed);
+ _installedLocales = (char **) uprv_malloc(sizeof(char*) * (localeCount+1));
+ if (_installedLocales != NULL) {
+ ures_resetIterator(&installed);
+ while(ures_hasNext(&installed)) {
+ ures_getNextString(&installed, NULL, (const char **)&_installedLocales[i++], &status);
}
+ _installedLocales[i] = NULL;
+ _installedLocalesCount = localeCount;
+ ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
}
- ures_close(&installed);
- ures_close(indexLocale);
}
+ ures_close(&installed);
+ ures_close(indexLocale);
+}
+
+static void _load_installedLocales()
+{
+ umtx_initOnce(_installedLocalesInitOnce, &loadInstalledLocales);
}
U_CAPI const char* U_EXPORT2
_load_installedLocales();
return _installedLocalesCount;
}
+