Quetionable code in i18n/ucol_res.cpp, in the function ucol_initUCA(), near line 110:
UBool needsInit;
UMTX_CHECK(NULL, (_staticUCA == NULL), needsInit);
if(needsInit) {
UDataMemory *result = udata_openChoice(NULL, UCA_DATA_TYPE, UCA_DATA_NAME, isAcceptableUCA, NULL, status);
if(U_SUCCESS(*status)){
UCollator *newUCA = ucol_initCollator((const UCATableHeader *)udata_getMemory(result), NULL, NULL, status);
if(U_SUCCESS(*status)){
umtx_lock(NULL);
if(_staticUCA == NULL) {
UCA_DATA_MEM = result;
_staticUCA = newUCA;
newUCA = NULL;
result = NULL;
}
umtx_unlock(NULL);
ucln_i18n_registerCleanup(UCLN_I18N_UCOL_RES, ucol_res_cleanup);
if(newUCA != NULL) {
ucol_close(newUCA);
udata_close(result);
}
// Initalize variables for implicit generation
uprv_uca_initImplicitConstants(status); <<<<<<<<<<<<<<<<<<<<
Is this thread safe?
initImplicitConstants() happens outside the mutex, and after _staticUCA is set, meaning that other threads could see the initialization as having completed without initImplicitConstants() having run.