-void
-ZoneMeta::initAvailableMetaZoneIDs () {
- UBool initialized;
- UMTX_CHECK(&gZoneMetaLock, gMetaZoneIDsInitialized, initialized);
- if (!initialized) {
- umtx_lock(&gZoneMetaLock);
- {
- if (!gMetaZoneIDsInitialized) {
- UErrorCode status = U_ZERO_ERROR;
- UHashtable *metaZoneIDTable = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, &status);
- uhash_setKeyDeleter(metaZoneIDTable, uprv_deleteUObject);
- // No valueDeleter, because the vector maintain the value objects
- UVector *metaZoneIDs = NULL;
- if (U_SUCCESS(status)) {
- metaZoneIDs = new UVector(NULL, uhash_compareUChars, status);
- if (metaZoneIDs == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- }
- } else {
- uhash_close(metaZoneIDTable);
- }
- if (U_SUCCESS(status)) {
- U_ASSERT(metaZoneIDs != NULL);
- metaZoneIDs->setDeleter(uprv_free);
-
- UResourceBundle *rb = ures_openDirect(NULL, gMetaZones, &status);
- UResourceBundle *bundle = ures_getByKey(rb, gMapTimezonesTag, NULL, &status);
- UResourceBundle res;
- ures_initStackObject(&res);
- while (U_SUCCESS(status) && ures_hasNext(bundle)) {
- ures_getNextResource(bundle, &res, &status);
- if (U_FAILURE(status)) {
- break;
- }
- const char *mzID = ures_getKey(&res);
- int32_t len = uprv_strlen(mzID);
- UChar *uMzID = (UChar*)uprv_malloc(sizeof(UChar) * (len + 1));
- if (uMzID == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- break;
- }
- u_charsToUChars(mzID, uMzID, len);
- uMzID[len] = 0;
- UnicodeString *usMzID = new UnicodeString(uMzID);
- if (uhash_get(metaZoneIDTable, usMzID) == NULL) {
- metaZoneIDs->addElement((void *)uMzID, status);
- uhash_put(metaZoneIDTable, (void *)usMzID, (void *)uMzID, &status);
- } else {
- uprv_free(uMzID);
- delete usMzID;
- }
- }
- if (U_SUCCESS(status)) {
- gMetaZoneIDs = metaZoneIDs;
- gMetaZoneIDTable = metaZoneIDTable;
- gMetaZoneIDsInitialized = TRUE;
- } else {
- uhash_close(metaZoneIDTable);
- delete metaZoneIDs;
- }
- ures_close(&res);
- ures_close(bundle);
- ures_close(rb);
- }
- }
+static void U_CALLCONV initAvailableMetaZoneIDs () {
+ U_ASSERT(gMetaZoneIDs == NULL);
+ U_ASSERT(gMetaZoneIDTable == NULL);
+ ucln_i18n_registerCleanup(UCLN_I18N_ZONEMETA, zoneMeta_cleanup);
+
+ UErrorCode status = U_ZERO_ERROR;
+ gMetaZoneIDTable = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, &status);
+ if (U_FAILURE(status) || gMetaZoneIDTable == NULL) {
+ gMetaZoneIDTable = NULL;
+ return;
+ }
+ uhash_setKeyDeleter(gMetaZoneIDTable, uprv_deleteUObject);
+ // No valueDeleter, because the vector maintain the value objects
+ gMetaZoneIDs = new UVector(NULL, uhash_compareUChars, status);
+ if (U_FAILURE(status) || gMetaZoneIDs == NULL) {
+ gMetaZoneIDs = NULL;
+ uhash_close(gMetaZoneIDTable);
+ gMetaZoneIDTable = NULL;
+ return;
+ }
+ gMetaZoneIDs->setDeleter(uprv_free);
+
+ UResourceBundle *rb = ures_openDirect(NULL, gMetaZones, &status);
+ UResourceBundle *bundle = ures_getByKey(rb, gMapTimezonesTag, NULL, &status);
+ UResourceBundle res;
+ ures_initStackObject(&res);
+ while (U_SUCCESS(status) && ures_hasNext(bundle)) {
+ ures_getNextResource(bundle, &res, &status);
+ if (U_FAILURE(status)) {
+ break;