ICU-6488 mutex cleanup in timezone code
X-SVN-Rev: 24452
This commit is contained in:
parent
1de383df48
commit
d13d3b6d4d
@ -107,6 +107,7 @@ static U_NAMESPACE_QUALIFIER TimeZone* DEFAULT_ZONE = NULL;
|
||||
static U_NAMESPACE_QUALIFIER TimeZone* _GMT = NULL; // cf. TimeZone::GMT
|
||||
|
||||
static char TZDATA_VERSION[16];
|
||||
static UBool TZDataVersionInitialized = FALSE;
|
||||
|
||||
#ifdef U_USE_TIMEZONE_OBSOLETE_2_8
|
||||
static U_NAMESPACE_QUALIFIER UnicodeString* OLSON_IDS = 0;
|
||||
@ -127,6 +128,7 @@ static UBool U_CALLCONV timeZone_cleanup(void)
|
||||
_GMT = NULL;
|
||||
|
||||
uprv_memset(TZDATA_VERSION, 0, sizeof(TZDATA_VERSION));
|
||||
TZDataVersionInitialized = FALSE;
|
||||
|
||||
if (LOCK) {
|
||||
umtx_destroy(&LOCK);
|
||||
@ -383,12 +385,15 @@ TimeZone::getGMT(void)
|
||||
// Initialize _GMT independently of other static data; it should
|
||||
// be valid even if we can't load the time zone UDataMemory.
|
||||
if (needsInit) {
|
||||
SimpleTimeZone *tmpGMT = new SimpleTimeZone(0, UnicodeString(TRUE, GMT_ID, GMT_ID_LENGTH));
|
||||
umtx_lock(&LOCK);
|
||||
if (_GMT == 0) {
|
||||
_GMT = new SimpleTimeZone(0, UnicodeString(TRUE, GMT_ID, GMT_ID_LENGTH));
|
||||
ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
|
||||
_GMT = tmpGMT;
|
||||
tmpGMT = NULL;
|
||||
}
|
||||
umtx_unlock(&LOCK);
|
||||
ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
|
||||
delete tmpGMT;
|
||||
}
|
||||
return _GMT;
|
||||
}
|
||||
@ -576,46 +581,6 @@ TimeZone::initDefault()
|
||||
default_zone = NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// NOTE: As of ICU 2.8, we no longer have an offsets table, since
|
||||
// historical zones can change offset over time. If we add
|
||||
// build-time heuristics to infer the "most frequent" raw offset
|
||||
// of a zone, we can build tables and institute defaults, as done
|
||||
// in ICU <= 2.6.
|
||||
|
||||
// If we couldn't get the time zone ID from the host, use
|
||||
// the default host timezone offset. Further refinements
|
||||
// to this include querying the host to determine if DST
|
||||
// is in use or not and possibly using the host locale to
|
||||
// select from multiple zones at a the same offset. We
|
||||
// don't do any of this now, but we could easily add this.
|
||||
if (default_zone == NULL) {
|
||||
// Use the designated default in the time zone list that has the
|
||||
// appropriate GMT offset, if there is one.
|
||||
|
||||
const OffsetIndex* index = INDEX_BY_OFFSET;
|
||||
|
||||
for (;;) {
|
||||
if (index->gmtOffset > rawOffset) {
|
||||
// Went past our desired offset; no match found
|
||||
break;
|
||||
}
|
||||
if (index->gmtOffset == rawOffset) {
|
||||
// Found our desired offset
|
||||
default_zone = createSystemTimeZone(ZONE_IDS[index->defaultZone]);
|
||||
break;
|
||||
}
|
||||
// Compute the position of the next entry. If the delta value
|
||||
// in this entry is zero, then there is no next entry.
|
||||
uint16_t delta = index->nextEntryDelta;
|
||||
if (delta == 0) {
|
||||
break;
|
||||
}
|
||||
index = (const OffsetIndex*)((int8_t*)index + delta);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Construct a fixed standard zone with the host's ID
|
||||
// and raw offset.
|
||||
if (default_zone == NULL) {
|
||||
@ -669,7 +634,6 @@ TimeZone::adoptDefault(TimeZone* zone)
|
||||
{
|
||||
TimeZone* old = NULL;
|
||||
|
||||
umtx_init(&LOCK); /* This is here to prevent race conditions. */
|
||||
umtx_lock(&LOCK);
|
||||
old = DEFAULT_ZONE;
|
||||
DEFAULT_ZONE = zone;
|
||||
@ -1458,19 +1422,26 @@ TimeZone::getTZDataVersion(UErrorCode& status)
|
||||
{
|
||||
/* This is here to prevent race conditions. */
|
||||
UBool needsInit;
|
||||
UMTX_CHECK(&LOCK, (TZDATA_VERSION[0] == 0), needsInit);
|
||||
UMTX_CHECK(&LOCK, !TZDataVersionInitialized, needsInit);
|
||||
if (needsInit) {
|
||||
int32_t len = sizeof(TZDATA_VERSION);
|
||||
int32_t len = 0;
|
||||
UResourceBundle *bundle = ures_openDirect(NULL, "zoneinfo", &status);
|
||||
const UChar *tzver = ures_getStringByKey(bundle, "TZVersion",
|
||||
&len, &status);
|
||||
|
||||
umtx_lock(&LOCK);
|
||||
if (U_SUCCESS(status)) {
|
||||
u_UCharsToChars(tzver, TZDATA_VERSION, len+1);
|
||||
if (len >= sizeof(TZDATA_VERSION)) {
|
||||
// Ensure that there is always space for a trailing nul in TZDATA_VERSION
|
||||
len = sizeof(TZDATA_VERSION) - 1;
|
||||
}
|
||||
umtx_lock(&LOCK);
|
||||
if (!TZDataVersionInitialized) {
|
||||
u_UCharsToChars(tzver, TZDATA_VERSION, len);
|
||||
TZDataVersionInitialized = TRUE;
|
||||
}
|
||||
umtx_unlock(&LOCK);
|
||||
ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
|
||||
}
|
||||
umtx_unlock(&LOCK);
|
||||
|
||||
ures_close(bundle);
|
||||
}
|
||||
|
@ -664,19 +664,21 @@ ZoneMeta::initialize(void) {
|
||||
Hashtable *tmpMetaToOlson = createMetaToOlsonMap();
|
||||
|
||||
umtx_lock(&gZoneMetaLock);
|
||||
if (gZoneMetaInitialized) {
|
||||
// Another thread already created mappings
|
||||
delete tmpCanonicalMap;
|
||||
delete tmpOlsonToMeta;
|
||||
delete tmpMetaToOlson;
|
||||
} else {
|
||||
if (!gZoneMetaInitialized) {
|
||||
gCanonicalMap = tmpCanonicalMap;
|
||||
gOlsonToMeta = tmpOlsonToMeta;
|
||||
gMetaToOlson = tmpMetaToOlson;
|
||||
tmpCanonicalMap = NULL;
|
||||
tmpOlsonToMeta = NULL;
|
||||
tmpMetaToOlson = NULL;
|
||||
gZoneMetaInitialized = TRUE;
|
||||
ucln_i18n_registerCleanup(UCLN_I18N_ZONEMETA, zoneMeta_cleanup);
|
||||
}
|
||||
umtx_unlock(&gZoneMetaLock);
|
||||
|
||||
ucln_i18n_registerCleanup(UCLN_I18N_ZONEMETA, zoneMeta_cleanup);
|
||||
delete tmpCanonicalMap;
|
||||
delete tmpOlsonToMeta;
|
||||
delete tmpMetaToOlson;
|
||||
}
|
||||
|
||||
UnicodeString& U_EXPORT2
|
||||
|
Loading…
Reference in New Issue
Block a user