]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/common/serv.cpp
ICU-64252.0.1.tar.gz
[apple/icu.git] / icuSources / common / serv.cpp
index 4f1da5bedc55f4abad276df75a95230b46cf983a..b92e4e400f3b27fc1b2db8bc801d29b8e0fcfdc9 100644 (file)
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /**
 *******************************************************************************
-* Copyright (C) 2001-2010, International Business Machines Corporation.
+* Copyright (C) 2001-2014, International Business Machines Corporation.
 * All Rights Reserved.
 *******************************************************************************
 */
@@ -102,7 +104,7 @@ UnicodeString&
 ICUServiceKey::debug(UnicodeString& result) const 
 {
     debugClass(result);
-    result.append(" id: ");
+    result.append((UnicodeString)" id: ");
     result.append(_id);
     return result;
 }
@@ -110,7 +112,7 @@ ICUServiceKey::debug(UnicodeString& result) const
 UnicodeString& 
 ICUServiceKey::debugClass(UnicodeString& result) const 
 {
-    return result.append("ICUServiceKey");
+    return result.append((UnicodeString)"ICUServiceKey");
 }
 #endif
 
@@ -120,6 +122,8 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ICUServiceKey)
 ******************************************************************
 */
 
+ICUServiceFactory::~ICUServiceFactory() {}
+
 SimpleFactory::SimpleFactory(UObject* instanceToAdopt, const UnicodeString& id, UBool visible) 
 : _instance(instanceToAdopt), _id(id), _visible(visible)
 {
@@ -168,17 +172,17 @@ UnicodeString&
 SimpleFactory::debug(UnicodeString& toAppendTo) const 
 {
     debugClass(toAppendTo);
-    toAppendTo.append(" id: ");
+    toAppendTo.append((UnicodeString)" id: ");
     toAppendTo.append(_id);
-    toAppendTo.append(", visible: ");
-    toAppendTo.append(_visible ? "T" : "F");
+    toAppendTo.append((UnicodeString)", visible: ");
+    toAppendTo.append(_visible ? (UnicodeString)"T" : (UnicodeString)"F");
     return toAppendTo;
 }
 
 UnicodeString& 
 SimpleFactory::debugClass(UnicodeString& toAppendTo) const 
 {
-    return toAppendTo.append("SimpleFactory");
+    return toAppendTo.append((UnicodeString)"SimpleFactory");
 }
 #endif
 
@@ -188,6 +192,8 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleFactory)
 ******************************************************************
 */
 
+ServiceListener::~ServiceListener() {}
+
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ServiceListener)
 
 /*
@@ -278,7 +284,7 @@ public:
     DNCache(const Locale& _locale) 
         : cache(), locale(_locale) 
     {
-        // cache.setKeyDeleter(uhash_deleteUnicodeString);
+        // cache.setKeyDeleter(uprv_deleteUObject);
     }
 };
 
@@ -327,39 +333,39 @@ U_CDECL_END
 ******************************************************************
 */
 
+static UMutex *lock() {
+    static UMutex *m = STATIC_NEW(UMutex);
+    return m;
+}
+
 ICUService::ICUService()
 : name()
-, lock(0)
 , timestamp(0)
 , factories(NULL)
 , serviceCache(NULL)
 , idCache(NULL)
 , dnCache(NULL)
 {
-    umtx_init(&lock);
 }
 
 ICUService::ICUService(const UnicodeString& newName) 
 : name(newName)
-, lock(0)
 , timestamp(0)
 , factories(NULL)
 , serviceCache(NULL)
 , idCache(NULL)
 , dnCache(NULL)
 {
-    umtx_init(&lock);
 }
 
 ICUService::~ICUService()
 {
     {
-        Mutex mutex(&lock);
+        Mutex mutex(lock());
         clearCaches();
         delete factories;
         factories = NULL;
     }
-    umtx_destroy(&lock);
 }
 
 UObject* 
@@ -400,7 +406,7 @@ ICUService::getKey(ICUServiceKey& key, UnicodeString* actualReturn, UErrorCode&
 // reentrantly even without knowing the thread.
 class XMutex : public UMemory {
 public:
-    inline XMutex(UMTX *mutex, UBool reentering) 
+    inline XMutex(UMutex *mutex, UBool reentering) 
         : fMutex(mutex)
         , fActive(!reentering) 
     {
@@ -411,7 +417,7 @@ public:
     }
 
 private:
-    UMTX  *fMutex;
+    UMutex  *fMutex;
     UBool fActive;
 };
 
@@ -446,7 +452,7 @@ ICUService::getKey(ICUServiceKey& key, UnicodeString* actualReturn, const ICUSer
         // if factory is not null, we're calling from within the mutex,
         // and since some unix machines don't have reentrant mutexes we
         // need to make sure not to try to lock it again.
-        XMutex mutex(&ncthis->lock, factory != NULL);
+        XMutex mutex(lock(), factory != NULL);
 
         if (serviceCache == NULL) {
             ncthis->serviceCache = new Hashtable(status);
@@ -522,7 +528,7 @@ ICUService::getKey(ICUServiceKey& key, UnicodeString* actualReturn, const ICUSer
             // fallback to the one that succeeded, we want to hit the
             // cache the first time next goaround.
             if (cacheDescriptorList._obj == NULL) {
-                cacheDescriptorList._obj = new UVector(uhash_deleteUnicodeString, NULL, 5, status);
+                cacheDescriptorList._obj = new UVector(uprv_deleteUObject, NULL, 5, status);
                 if (U_FAILURE(status)) {
                     return NULL;
                 }
@@ -544,16 +550,15 @@ outerEnd:
             if (putInCache && cacheResult) {
                 serviceCache->put(result->actualDescriptor, result, status);
                 if (U_FAILURE(status)) {
-                    delete result;
                     return NULL;
                 }
 
                 if (cacheDescriptorList._obj != NULL) {
                     for (int32_t i = cacheDescriptorList._obj->size(); --i >= 0;) {
                         UnicodeString* desc = (UnicodeString*)cacheDescriptorList._obj->elementAt(i);
+
                         serviceCache->put(*desc, result, status);
                         if (U_FAILURE(status)) {
-                            delete result;
                             return NULL;
                         }
 
@@ -612,14 +617,13 @@ ICUService::getVisibleIDs(UVector& result, const UnicodeString* matchID, UErrorC
         return result;
     }
 
-    ICUService * ncthis = (ICUService*)this; // cast away semantic const
     {
-        Mutex mutex(&ncthis->lock);
+        Mutex mutex(lock());
         const Hashtable* map = getVisibleIDMap(status);
         if (map != NULL) {
             ICUServiceKey* fallbackKey = createKey(matchID, status);
 
-            for (int32_t pos = -1;;) {
+            for (int32_t pos = UHASH_FIRST;;) {
                 const UHashElement* e = map->nextElement(pos);
                 if (e == NULL) {
                     break;
@@ -690,9 +694,8 @@ UnicodeString&
 ICUService::getDisplayName(const UnicodeString& id, UnicodeString& result, const Locale& locale) const 
 {
     {
-        ICUService* ncthis = (ICUService*)this; // cast away semantic const
         UErrorCode status = U_ZERO_ERROR;
-        Mutex mutex(&ncthis->lock);
+        Mutex mutex(lock());
         const Hashtable* map = getVisibleIDMap(status);
         if (map != NULL) {
             ICUServiceFactory* f = (ICUServiceFactory*)map->get(id);
@@ -702,9 +705,9 @@ ICUService::getDisplayName(const UnicodeString& id, UnicodeString& result, const
             }
 
             // fallback
-            UErrorCode status = U_ZERO_ERROR;
+            status = U_ZERO_ERROR;
             ICUServiceKey* fallbackKey = createKey(&id, status);
-            while (fallbackKey->fallback()) {
+            while (fallbackKey != NULL && fallbackKey->fallback()) {
                 UnicodeString us;
                 fallbackKey->currentID(us);
                 f = (ICUServiceFactory*)map->get(us);
@@ -744,7 +747,7 @@ ICUService::getDisplayNames(UVector& result,
     result.setDeleter(userv_deleteStringPair);
     if (U_SUCCESS(status)) {
         ICUService* ncthis = (ICUService*)this; // cast away semantic const
-        Mutex mutex(&ncthis->lock);
+        Mutex mutex(lock());
 
         if (dnCache != NULL && dnCache->locale != locale) {
             delete dnCache;
@@ -753,32 +756,33 @@ ICUService::getDisplayNames(UVector& result,
 
         if (dnCache == NULL) {
             const Hashtable* m = getVisibleIDMap(status);
-            if (m != NULL) {
-                ncthis->dnCache = new DNCache(locale); 
-                if (dnCache == NULL) {
-                    status = U_MEMORY_ALLOCATION_ERROR;
-                    return result;
-                }
+            if (U_FAILURE(status)) {
+                return result;
+            }
+            ncthis->dnCache = new DNCache(locale); 
+            if (dnCache == NULL) {
+                status = U_MEMORY_ALLOCATION_ERROR;
+                return result;
+            }
 
-                int32_t pos = -1;
-                const UHashElement* entry = NULL;
-                while ((entry = m->nextElement(pos)) != NULL) {
-                    const UnicodeString* id = (const UnicodeString*)entry->key.pointer;
-                    ICUServiceFactory* f = (ICUServiceFactory*)entry->value.pointer;
-                    UnicodeString dname;
-                    f->getDisplayName(*id, locale, dname);
-                    if (dname.isBogus()) {
-                        status = U_MEMORY_ALLOCATION_ERROR;
-                    } else {
-                        dnCache->cache.put(dname, (void*)id, status); // share pointer with visibleIDMap
-                        if (U_SUCCESS(status)) {
-                            continue;
-                        }
+            int32_t pos = UHASH_FIRST;
+            const UHashElement* entry = NULL;
+            while ((entry = m->nextElement(pos)) != NULL) {
+                const UnicodeString* id = (const UnicodeString*)entry->key.pointer;
+                ICUServiceFactory* f = (ICUServiceFactory*)entry->value.pointer;
+                UnicodeString dname;
+                f->getDisplayName(*id, locale, dname);
+                if (dname.isBogus()) {
+                    status = U_MEMORY_ALLOCATION_ERROR;
+                } else {
+                    dnCache->cache.put(dname, (void*)id, status); // share pointer with visibleIDMap
+                    if (U_SUCCESS(status)) {
+                        continue;
                     }
-                    delete dnCache;
-                    ncthis->dnCache = NULL;
-                    return result;
                 }
+                delete dnCache;
+                ncthis->dnCache = NULL;
+                return result;
             }
         }
     }
@@ -788,7 +792,7 @@ ICUService::getDisplayNames(UVector& result,
      * nextElement(pos) will skip the position at pos and begin the iteration
      * at the next position, which in this case will be 0.
      */
-    int32_t pos = -1
+    int32_t pos = UHASH_FIRST
     const UHashElement *entry = NULL;
     while ((entry = dnCache->cache.nextElement(pos)) != NULL) {
         const UnicodeString* id = (const UnicodeString*)entry->value.pointer;
@@ -848,7 +852,7 @@ URegistryKey
 ICUService::registerFactory(ICUServiceFactory* factoryToAdopt, UErrorCode& status) 
 {
     if (U_SUCCESS(status) && factoryToAdopt != NULL) {
-        Mutex mutex(&lock);
+        Mutex mutex(lock());
 
         if (factories == NULL) {
             factories = new UVector(deleteUObject, NULL, status);
@@ -879,7 +883,7 @@ ICUService::unregister(URegistryKey rkey, UErrorCode& status)
     ICUServiceFactory *factory = (ICUServiceFactory*)rkey;
     UBool result = FALSE;
     if (factory != NULL && factories != NULL) {
-        Mutex mutex(&lock);
+        Mutex mutex(lock());
 
         if (factories->removeElement(factory)) {
             clearCaches();
@@ -899,7 +903,7 @@ void
 ICUService::reset() 
 {
     {
-        Mutex mutex(&lock);
+        Mutex mutex(lock());
         reInitializeFactories();
         clearCaches();
     }