Update for thread-safety of AppResource
authorJaesung Ku <jaesung.ku@samsung.com>
Thu, 8 Aug 2013 06:03:26 +0000 (15:03 +0900)
committerJaesung Ku <jaesung.ku@samsung.com>
Thu, 8 Aug 2013 06:12:37 +0000 (15:12 +0900)
Change-Id: Ib17a1806f224940c8478a7719d12942dc404c257
Signed-off-by: Jaesung Ku <jaesung.ku@samsung.com>
src/app/FApp_AppResourceImpl.cpp
src/app/FApp_AppResourceImpl.h

index d01befb..a258b1f 100644 (file)
@@ -50,6 +50,7 @@ namespace Tizen { namespace App
 static _IAppResourceBitmap*(* p_Create_IAppResourceBitmapInstanceN)(int type, const String& value) = null;
 
 Tizen::Base::Collection::HashMap* _AppResourceImpl::__pContainer = null;
+Tizen::Base::Runtime::Mutex* _AppResourceImpl::__pLock = null;
 
 _AppResourceImpl::_AppResourceImpl(void)
        : __p_AppResourceString(null)
@@ -62,15 +63,23 @@ _AppResourceImpl::_AppResourceImpl(void)
 result
 _AppResourceImpl::ReleaseInstance(const Tizen::Base::String& key)
 {
+       result ret = E_SUCCESS;
+
        if (__pContainer != null)
        {
+               result r = __pLock->Acquire();
+               SysTryLog(NID_APP, !IsFailed(r), "Failed to acquire mutex.");
+
                AppResource* pAppResource = static_cast<AppResource*> (__pContainer->GetValue(key));
                delete pAppResource;
 
-               return __pContainer->Remove(key);
+               ret = __pContainer->Remove(key);
+
+               r = __pLock->Release();
+               SysTryLog(NID_APP, !IsFailed(r), "Failed to release mutex.");
        }
 
-       return E_SUCCESS;
+       return ret;
 }
 
 // Exception: E_OUT_OF_MEMORY, E_SYSTEM, E_INVALID_ARG, E_OBJ_NOT_FOUND, E_APP_NOT_INSTALLED [Get_AppResourceStringN], Get_IAppResourceBitmapN
@@ -78,39 +87,41 @@ AppResource*
 _AppResourceImpl::GetInstanceN(AppResourceBy type, const Tizen::Base::String& value)
 {
        result r = E_SUCCESS;
+       static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
        if (__pContainer == null)
        {
-               std::unique_ptr< HashMap > pContainer(new (std::nothrow) HashMap());
-               SysTryReturn(NID_APP, pContainer != null,
-                               null, E_OUT_OF_MEMORY, "[%s] Creating the container is failed.", GetErrorMessage(E_OUT_OF_MEMORY));
-
-               r = pContainer->Construct();
+               ClearLastResult();
+               pthread_once(&onceBlock, InitSingleton);
+               r = GetLastResult();
                SysTryReturn(NID_APP, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Creating the container is failed [%s].", GetErrorMessage(r));
-
-               __pContainer = pContainer.release();
        }
 
+       r = __pLock->Acquire();
+       SysTryLog(NID_APP, !IsFailed(r), "Failed to acquire mutex.");
+
        bool hasAppResource = false;
        r = __pContainer->ContainsKey(value, hasAppResource);
-       SysTryReturn(NID_APP, !IsFailed(r), null, r, "[%s] Checking to contain is failed.", GetErrorMessage(r));
+       SysTryCatch(NID_APP, !IsFailed(r), r, r, "[%s] Checking to contain is failed.", GetErrorMessage(r));
 
        if (hasAppResource)
        {
+               r = __pLock->Release();
+               SysTryLog(NID_APP, !IsFailed(r), "Failed to release mutex.");
+
                return static_cast<AppResource*> (__pContainer->GetValue(value));
        }
        else
        {
                std::unique_ptr< _AppResourceImpl > pAppResourceImpl(new (std::nothrow) _AppResourceImpl());
-               SysTryReturn(NID_APP, pAppResourceImpl != null,
-                               null, E_OUT_OF_MEMORY, "[%s] Unable to allocate memory for AppResourceImpl.", GetErrorMessage(E_OUT_OF_MEMORY));
+               SysTryCatch(NID_APP, pAppResourceImpl != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,"[E_OUT_OF_MEMORY] Unable to allocate memory for AppResourceImpl.");
 
                std::unique_ptr< _AppResourceString > pAppResourceString(_AppResourceString::Get_AppResourceStringN(type, value));
                r = GetLastResult();
-               SysTryReturn(NID_APP, !IsFailed(r), null, r, "[%s] Unable to get _AppResourceString.", GetErrorMessage(r));
+               SysTryCatch(NID_APP, !IsFailed(r), r, r, "[%s] Unable to get _AppResourceString.", GetErrorMessage(r));
 
                std::unique_ptr< _IAppResourceBitmap > pAppResourceBitmap(Get_IAppResourceBitmapN(type, value));
                r = GetLastResult();
-               SysTryReturn(NID_APP, !IsFailed(r), null, r, "[%s] Unable to get _IAppResourceBitmap.", GetErrorMessage(r));
+               SysTryCatch(NID_APP, !IsFailed(r), r, r, "[%s] Unable to get _IAppResourceBitmap.", GetErrorMessage(r));
 
                pAppResourceImpl->__p_AppResourceString = pAppResourceString.release();
                pAppResourceImpl->__p_IAppResourceBitmap = pAppResourceBitmap.release();
@@ -118,25 +129,34 @@ _AppResourceImpl::GetInstanceN(AppResourceBy type, const Tizen::Base::String& va
                pAppResourceImpl->__value = value;
 
                std::unique_ptr< String > pStr(new (std::nothrow) String(value));
-               SysTryReturn(NID_APP, pStr != null, null,
-                               E_OUT_OF_MEMORY, "[%s] Creating a key is failed.", GetErrorMessage(E_OUT_OF_MEMORY));
+               SysTryCatch(NID_APP, pStr != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Creating a key is failed.");
 
                AppResource* pAppResource = new (std::nothrow) AppResource;
-               SysTryReturn(NID_APP, pAppResource != null, null,
-                               E_OUT_OF_MEMORY, "[%s] Unable to allocate memory for AppResource", GetErrorMessage(E_OUT_OF_MEMORY));
+               SysTryCatch(NID_APP, pAppResource != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Unable to allocate memory for AppResource");
 
                pAppResource->__pAppResourceImpl = pAppResourceImpl.release();
                r = __pContainer->Add(*pStr, *pAppResource);
                if (IsFailed(r))
                {
                        delete pAppResource;
-                       SysTryReturn(NID_APP, false, null,
-                               E_SYSTEM, "[E_SYSTEM] Adding an element to the container is failed [%s].", GetErrorMessage(r));
+                       SysTryCatch(NID_APP, false, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Adding an element to the container is failed.");
                }
 
                pStr.release();
+
+               r = __pLock->Release();
+               SysTryLog(NID_APP, !IsFailed(r), "Failed to release mutex.");
+
                return pAppResource;
        }
+
+       // fall thru
+CATCH:
+       SetLastResult(r);
+
+       r = __pLock->Release();
+       SysTryLog(NID_APP, !IsFailed(r), "Failed to release mutex.");
+
        return null;
 }
 
@@ -217,9 +237,9 @@ _AppResourceImpl::Reinitialize(void)
                return;
        }
 
-       if (pThis->__pContainer != null)
+       if (__pContainer != null)
        {
-               std::unique_ptr< IMapEnumerator > pMapEnum(pThis->__pContainer->GetMapEnumeratorN());
+               std::unique_ptr< IMapEnumerator > pMapEnum(__pContainer->GetMapEnumeratorN());
                if (pMapEnum)
                {
                        while(pMapEnum->MoveNext() == E_SUCCESS)
@@ -256,4 +276,33 @@ _AppResourceImpl::GetNonScalingBitmapN(const Tizen::Base::String& imagePath)
        }
 }
 
+void
+_AppResourceImpl::InitSingleton(void)
+{
+       std::unique_ptr< HashMap > pContainer(new (std::nothrow) HashMap(SingleObjectDeleter));
+       SysTryReturnVoidResult(NID_APP, pContainer != null, E_OUT_OF_MEMORY, "[%s] Creating the container is failed.");
+
+       result r = pContainer->Construct();
+       SysTryReturnVoidResult(NID_APP, !IsFailed(r), E_SYSTEM, "[E_SYSTEM] Constructing the container is failed.");
+
+       __pContainer = pContainer.release();
+
+       std::unique_ptr< Mutex > pLock(new (std::nothrow) Mutex());
+       SysTryReturnVoidResult(NID_APP, pLock != null, E_OUT_OF_MEMORY, "[%s] Creating the mutex is failed.");
+
+       r = pLock->Create();
+       SysTryReturnVoidResult(NID_APP, !IsFailed(r), E_SYSTEM, "[E_SYSTEM] Constructing the mutex is failed.");
+
+       __pLock = pLock.release();
+
+       std::atexit(DestroySingleton);
+}
+
+void
+_AppResourceImpl::DestroySingleton(void)
+{
+       delete __pContainer;
+       delete __pLock;
+}
+
 } } // Tizen::App
index 0cface6..4d0a836 100644 (file)
@@ -162,6 +162,9 @@ private:
         */
        _AppResourceImpl& operator =(const _AppResourceImpl& source);
 
+       static void InitSingleton(void);
+       static void DestroySingleton(void);
+
 private:
        _AppResourceString* __p_AppResourceString;
        _IAppResourceBitmap* __p_IAppResourceBitmap;
@@ -170,7 +173,7 @@ private:
        Tizen::Base::String __value;
 
        static Tizen::Base::Collection::HashMap* __pContainer;
-
+       static Tizen::Base::Runtime::Mutex* __pLock;
 }; // _AppResourceImpl
 
 } } // Tizen::App