#include "unicode/uenum.h"
#include "cmemory.h"
#include "cstring.h"
+#include "mutex.h"
#include "putilimp.h"
#include "tznames_impl.h"
#include "uassert.h"
}
TimeZoneNamesDelegate::TimeZoneNamesDelegate(const Locale& locale, UErrorCode& status) {
- UBool initialized;
- UMTX_CHECK(&gTimeZoneNamesLock, gTimeZoneNamesCacheInitialized, initialized);
- if (!initialized) {
- // Create empty hashtable
- umtx_lock(&gTimeZoneNamesLock);
- {
- if (!gTimeZoneNamesCacheInitialized) {
- gTimeZoneNamesCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status);
- if (U_SUCCESS(status)) {
- uhash_setKeyDeleter(gTimeZoneNamesCache, uprv_free);
- uhash_setValueDeleter(gTimeZoneNamesCache, deleteTimeZoneNamesCacheEntry);
- gTimeZoneNamesCacheInitialized = TRUE;
- ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONENAMES, timeZoneNames_cleanup);
- }
- }
+ Mutex lock(&gTimeZoneNamesLock);
+ if (!gTimeZoneNamesCacheInitialized) {
+ // Create empty hashtable if it is not already initialized.
+ gTimeZoneNamesCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status);
+ if (U_SUCCESS(status)) {
+ uhash_setKeyDeleter(gTimeZoneNamesCache, uprv_free);
+ uhash_setValueDeleter(gTimeZoneNamesCache, deleteTimeZoneNamesCacheEntry);
+ gTimeZoneNamesCacheInitialized = TRUE;
+ ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONENAMES, timeZoneNames_cleanup);
}
- umtx_unlock(&gTimeZoneNamesLock);
+ }
- if (U_FAILURE(status)) {
- return;
- }
+ if (U_FAILURE(status)) {
+ return;
}
// Check the cache, if not available, create new one and cache
TimeZoneNamesCacheEntry *cacheEntry = NULL;
- umtx_lock(&gTimeZoneNamesLock);
- {
- const char *key = locale.getName();
- cacheEntry = (TimeZoneNamesCacheEntry *)uhash_get(gTimeZoneNamesCache, key);
- if (cacheEntry == NULL) {
- TimeZoneNames *tznames = NULL;
- char *newKey = NULL;
-
- tznames = new TimeZoneNamesImpl(locale, status);
- if (tznames == NULL) {
+
+ const char *key = locale.getName();
+ cacheEntry = (TimeZoneNamesCacheEntry *)uhash_get(gTimeZoneNamesCache, key);
+ if (cacheEntry == NULL) {
+ TimeZoneNames *tznames = NULL;
+ char *newKey = NULL;
+
+ tznames = new TimeZoneNamesImpl(locale, status);
+ if (tznames == NULL) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ }
+ if (U_SUCCESS(status)) {
+ newKey = (char *)uprv_malloc(uprv_strlen(key) + 1);
+ if (newKey == NULL) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ } else {
+ uprv_strcpy(newKey, key);
+ }
+ }
+ if (U_SUCCESS(status)) {
+ cacheEntry = (TimeZoneNamesCacheEntry *)uprv_malloc(sizeof(TimeZoneNamesCacheEntry));
+ if (cacheEntry == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
+ } else {
+ cacheEntry->names = tznames;
+ cacheEntry->refCount = 1;
+ cacheEntry->lastAccess = (double)uprv_getUTCtime();
+
+ uhash_put(gTimeZoneNamesCache, newKey, cacheEntry, &status);
}
- if (U_SUCCESS(status)) {
- newKey = (char *)uprv_malloc(uprv_strlen(key) + 1);
- if (newKey == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- } else {
- uprv_strcpy(newKey, key);
- }
+ }
+ if (U_FAILURE(status)) {
+ if (tznames != NULL) {
+ delete tznames;
}
- if (U_SUCCESS(status)) {
- cacheEntry = (TimeZoneNamesCacheEntry *)uprv_malloc(sizeof(TimeZoneNamesCacheEntry));
- if (cacheEntry == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- } else {
- cacheEntry->names = tznames;
- cacheEntry->refCount = 1;
- cacheEntry->lastAccess = (double)uprv_getUTCtime();
-
- uhash_put(gTimeZoneNamesCache, newKey, cacheEntry, &status);
- }
+ if (newKey != NULL) {
+ uprv_free(newKey);
}
- if (U_FAILURE(status)) {
- if (tznames != NULL) {
- delete tznames;
- }
- if (newKey != NULL) {
- uprv_free(newKey);
- }
- if (cacheEntry != NULL) {
- uprv_free(cacheEntry);
- }
- cacheEntry = NULL;
+ if (cacheEntry != NULL) {
+ uprv_free(cacheEntry);
}
- } else {
- // Update the reference count
- cacheEntry->refCount++;
- cacheEntry->lastAccess = (double)uprv_getUTCtime();
- }
- gAccessCount++;
- if (gAccessCount >= SWEEP_INTERVAL) {
- // sweep
- sweepCache();
- gAccessCount = 0;
+ cacheEntry = NULL;
}
+ } else {
+ // Update the reference count
+ cacheEntry->refCount++;
+ cacheEntry->lastAccess = (double)uprv_getUTCtime();
+ }
+ gAccessCount++;
+ if (gAccessCount >= SWEEP_INTERVAL) {
+ // sweep
+ sweepCache();
+ gAccessCount = 0;
}
- umtx_unlock(&gTimeZoneNamesLock);
-
fTZnamesCacheEntry = cacheEntry;
}