Modify DataControl manager for thread-safe
[platform/framework/native/appfw.git] / src / app / FApp_AppResourceImpl.cpp
index 7e8c60c..94b0a09 100644 (file)
@@ -1,5 +1,4 @@
 //
-// Open Service Platform
 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
 //
 // Licensed under the Apache License, Version 2.0 (the License);
@@ -51,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)
@@ -63,15 +63,20 @@ _AppResourceImpl::_AppResourceImpl(void)
 result
 _AppResourceImpl::ReleaseInstance(const Tizen::Base::String& key)
 {
+       result ret = E_SUCCESS;
+
        if (__pContainer != null)
        {
-               AppResource* pAppResource = static_cast<AppResource*> (__pContainer->GetValue(key));
-               delete pAppResource;
+               result r = __pLock->Acquire();
+               SysTryLog(NID_APP, !IsFailed(r), "Failed to acquire mutex.");
+
+               ret = __pContainer->Remove(key);
 
-               return __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
@@ -79,39 +84,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 == true)
+       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();
@@ -119,25 +126,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;
 }
 
@@ -218,9 +234,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)
@@ -248,12 +264,42 @@ _AppResourceImpl::GetNonScalingBitmapN(const Tizen::Base::String& imagePath)
 
        if (pAppResourceBitmap != null)
        {
-               return pAppResourceBitmap->GetBitmapN(imagePath, BITMAP_PIXEL_FORMAT_INVALID);
+               return pAppResourceBitmap->GetBitmapN(imagePath, BITMAP_PIXEL_FORMAT_INVALID, false);
        }
        else
        {
                SysLog(NID_APP, "Getting pAppResourceBitmap instance is failed");
+               return null;
        }
 }
 
+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