]> granicus.if.org Git - icu/commitdiff
ICU-11051 Add synchronization to u_getDataDirectory().
authorAndy Heninger <andy.heninger@gmail.com>
Thu, 14 Aug 2014 20:34:06 +0000 (20:34 +0000)
committerAndy Heninger <andy.heninger@gmail.com>
Thu, 14 Aug 2014 20:34:06 +0000 (20:34 +0000)
X-SVN-Rev: 36165

icu4c/source/common/putil.cpp

index 388b6aabed0395872a05eb7b93050c2af0fe2045..0e01355278f64e85e74f7ade07648d3204738b96 100644 (file)
@@ -1112,7 +1112,10 @@ uprv_tzname(int n)
 
 /* Get and set the ICU data directory --------------------------------------- */
 
+static icu::UInitOnce gDataDirInitOnce = U_INITONCE_INITIALIZER;
 static char *gDataDirectory = NULL;
+
+
 #if U_POSIX_LOCALE || U_PLATFORM_USES_ONLY_WIN32_API
  static char *gCorrectedPOSIXLocale = NULL; /* Heap allocated */
 #endif
@@ -1123,6 +1126,8 @@ static UBool U_CALLCONV putil_cleanup(void)
         uprv_free(gDataDirectory);
     }
     gDataDirectory = NULL;
+    gDataDirInitOnce.reset();
+
 #if U_POSIX_LOCALE || U_PLATFORM_USES_ONLY_WIN32_API
     if (gCorrectedPOSIXLocale) {
         uprv_free(gCorrectedPOSIXLocale);
@@ -1210,18 +1215,19 @@ uprv_pathIsAbsolute(const char *path)
 # endif
 #endif
 
-U_CAPI const char * U_EXPORT2
-u_getDataDirectory(void) {
+static void U_CALLCONV dataDirectoryInitFn() {
+    /* If we already have the directory, then return immediately. Will happen if user called
+     * u_setDataDirectory().
+     */
+    if (gDataDirectory) {
+        return;
+    }
+
     const char *path = NULL;
 #if defined(ICU_DATA_DIR_PREFIX_ENV_VAR)
     char datadir_path_buffer[PATH_MAX];
 #endif
 
-    /* if we have the directory, then return it immediately */
-    if(gDataDirectory) {
-        return gDataDirectory;
-    }
-
     /*
     When ICU_NO_USER_DATA_OVERRIDE is defined, users aren't allowed to
     override ICU's data with the ICU_DATA environment variable. This prevents
@@ -1272,6 +1278,12 @@ u_getDataDirectory(void) {
     }
 
     u_setDataDirectory(path);
+    return;
+}
+
+U_CAPI const char * U_EXPORT2
+u_getDataDirectory(void) {
+    umtx_initOnce(gDataDirInitOnce, &dataDirectoryInitFn);
     return gDataDirectory;
 }