Fixed memory leaks.
authorkyeongwoo.lee <kyeongwoo.lee@samsung.com>
Tue, 13 Aug 2013 08:15:52 +0000 (17:15 +0900)
committerkyeongwoo.lee <kyeongwoo.lee@samsung.com>
Tue, 13 Aug 2013 08:15:52 +0000 (17:15 +0900)
Change-Id: Ibb6c241296d581ff424b41243257fef8c89f8621

inc/FShell_AppContext.h
inc/FShell_AppWidgetManagerService.h
src/FShell_AppContext.cpp
src/FShell_AppWidgetManagerService.cpp

index d888b413cc74f22dee87bf11c822b3b01960c39d..f4df21dc13d4399797d64578b1261ca3edfb0aab 100644 (file)
@@ -83,7 +83,7 @@ public:
        int GetClientId(void) const;
 
        _AppWidgetContext* FindAppWidget(const Tizen::Base::String& instanceId) const;
-       int GetProviderCount(const Tizen::Base::String& appId) const;
+       int GetProviderCount(void) const;
 
        result RequestUpdateInstance(const Tizen::Base::String& instanceId, const Tizen::Base::String& argument);
        result AcquireRemoteBuffer(const Tizen::Base::String& instanceId, int width, int height, int& bufferId);
index be4f5ca23c5a5eb3de9f6df52b7d6d0c501197ad..28b78f2949a9a0814ebf288c8c3d04ad2380cb0b 100644 (file)
@@ -55,10 +55,10 @@ public:
        result AddAppWidget(const Tizen::Base::String& userInfo, const Tizen::Base::String& appId, const Tizen::Base::String& instanceId, int width, int height, int period, int priority);
        result RequestUpdate(_AppWidgetContext* pAppWidgetContext, const Tizen::Base::String& argument) const;
        void OnUserEventReceivedN(RequestId reqId, Tizen::Base::Collection::IList* pArgs);
+       virtual ~AppWidgetManagerService(void);
 
 private:
        AppWidgetManagerService(void);
-       virtual ~AppWidgetManagerService(void);
        result Construct(const char* pServiceIdForCoreDaemon);
 
        result InitializeCoreDaemonEventReceiver(const char* pServiceIdForCoreDaemon);
@@ -107,10 +107,13 @@ private:
 
        // helpers
        _AppContext* FindAppContext(const Tizen::App::AppId& appId) const;
+       result RemoveAppContext(const Tizen::App::AppId& appId);
        _AppWidgetContext* FindAppWidget(const Tizen::App::AppId& appId, const Tizen::Base::String& instanceId) const;
        void StartPingTimer(void);
        virtual void OnTimerExpired(Tizen::Base::Runtime::Timer& timer);
        result RequestUpdateAllSuspened(void) const;
+       static void InitSingleton(void);
+       static void DestroySingleton(void);
 
 private:
        static AppWidgetManagerService* __pTheInstance;
index 19d3ad0fffe4cfc85df3e146c850e76a3f765b54..5c5f942ce364dbd7ca3a4b456400e58541b2502a 100644 (file)
@@ -24,6 +24,7 @@
 #include <FBase.h>
 #include <FBaseSysLog.h>
 #include <FBaseColHashMap.h>
+#include <FBaseColIMapEnumeratorT.h>
 #include <FAppApp.h>
 #include <FBaseComparerT.h>
 #include <FApp_AppManagerImpl.h>
@@ -65,6 +66,8 @@ _AppContext::_AppContext(const AppId& appId)
 
 _AppContext::~_AppContext(void)
 {
+       SysLog(NID_SHELL, "Enter");
+
        if (__pPendingEventList)
        {
                for (int i = 0; i < __pPendingEventList->GetCount(); i++)
@@ -76,6 +79,21 @@ _AppContext::~_AppContext(void)
                __pPendingEventList->RemoveAll();
                delete __pPendingEventList;
        }
+
+       IMapEnumeratorT<String, _AppWidgetContext*>* pMapEnum = __appWidgetContextList.GetMapEnumeratorN();
+       if (pMapEnum != null)
+       {
+               while (pMapEnum->MoveNext() == E_SUCCESS)
+               {
+                       _AppWidgetContext* pAppWidgetContext = null;
+                       pMapEnum->GetValue(pAppWidgetContext);
+                       delete pAppWidgetContext;
+               }
+
+               delete pMapEnum;
+       }
+
+       SysLog(NID_SHELL, "Exit");
 }
 
 result
@@ -365,7 +383,7 @@ _AppContext::FindInvalidAppWidget(void) const
 }
 
 int
-_AppContext::GetProviderCount(const String& appId) const
+_AppContext::GetProviderCount(void) const
 {
        return __appWidgetContextList.GetCount();
 }
index 0b1a99911c9c2a251018a2dc024d22fdd367f3f3..092decfccb80f97b94a4d114a3e18db33d60bbde 100644 (file)
@@ -67,10 +67,42 @@ AppWidgetManagerService::AppWidgetManagerService(void)
 
 AppWidgetManagerService::~AppWidgetManagerService(void)
 {
-       SysLog(NID_SHELL, "Enter.");
+       SysLog(NID_SHELL, "Enter");
+
        __pingTimer.Cancel();
+
        DeinitializeCoreDaemonEventReceiver();
-       SysLog(NID_SHELL, "Exit.");
+
+       IMapEnumeratorT<String, _AppContext*>* pMapEnum = __appContextList.GetMapEnumeratorN();
+       if (pMapEnum != null)
+       {
+               while (pMapEnum->MoveNext() == E_SUCCESS)
+               {
+                       _AppContext* pAppContext = null;
+                       pMapEnum->GetValue(pAppContext);
+                       delete pAppContext;
+               }
+
+               delete pMapEnum;
+       }
+
+       SysLog(NID_SHELL, "Exit");
+}
+
+void
+AppWidgetManagerService::InitSingleton(void)
+{
+       unique_ptr<AppWidgetManagerService> pInstance(new (nothrow) AppWidgetManagerService());
+       SysTryReturnVoidResult(NID_SHELL, pInstance, E_OUT_OF_MEMORY, "The memory is insufficient.");
+
+       __pTheInstance = pInstance.release();
+       std::atexit(DestroySingleton);
+}
+
+void
+AppWidgetManagerService::DestroySingleton(void)
+{
+       delete __pTheInstance;
 }
 
 AppWidgetManagerService*
@@ -86,12 +118,20 @@ AppWidgetManagerService::GetInstance(void)
 AppWidgetManagerService*
 AppWidgetManagerService::CreateInstance(const char* pCoreDaemonId)
 {
+       ClearLastResult();
+
+       static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
+
        if (__pTheInstance == null)
        {
-               __pTheInstance = new AppWidgetManagerService();
-               SysTryReturn(NID_SHELL, __pTheInstance != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]");
+               pthread_once(&onceBlock, InitSingleton);
+               result r = GetLastResult();
+               if (IsFailed(r))
+               {
+                       onceBlock = PTHREAD_ONCE_INIT;
+               }
 
-               result r = __pTheInstance->Construct(pCoreDaemonId);
+               r = __pTheInstance->Construct(pCoreDaemonId);
                SysAssertf(!IsFailed(r), "Failed to construct AppWidgetManagerService");
                SysLog(NID_SHELL, "AppWidgetManagerService is created.");
        }
@@ -164,6 +204,12 @@ AppWidgetManagerService::FindAppContext(const Tizen::App::AppId& appId) const
        return pAppContext;
 }
 
+result
+AppWidgetManagerService::RemoveAppContext(const Tizen::App::AppId& appId)
+{
+       return __appContextList.Remove(appId);
+}
+
 _AppWidgetContext*
 AppWidgetManagerService::FindAppWidget(const AppId& appId, const String& instanceId) const
 {
@@ -296,11 +342,19 @@ AppWidgetManagerService::OnAppWidgetDestroy(struct event_arg *arg, void* data)
 {
        SysAssertf(arg != null && arg->type == event_arg::EVENT_DELETE, "The status of data-provider-master is invalid.");
 
-       _AppContext* pAppContext = AppWidgetManagerService::GetInstance()->FindAppContext(_AppWidgetHelper::ExtractAppId(arg->pkgname));
+       String appId = _AppWidgetHelper::ExtractAppId(arg->pkgname);
+       _AppContext* pAppContext = AppWidgetManagerService::GetInstance()->FindAppContext(appId);
        SysTryReturn(NID_SHELL, pAppContext != null, -1, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Failed to find _AppContext.");
 
        pAppContext->DestroyAppWidget(arg->id);
 
+       if (pAppContext->GetProviderCount() == 0)
+       {
+               SysLog(NID_SHELL, "The provider count for (%ls) is 0.", appId.GetPointer());
+               AppWidgetManagerService::GetInstance()->RemoveAppContext(appId);
+               delete pAppContext;
+       }
+
        return 0;
 }
 
@@ -611,7 +665,7 @@ AppWidgetManagerService::RequestProviderCount(const Tizen::App::AppId& appId, co
        result r = __appContextList.GetValue(appId, pAppContext);
        SysTryReturnResult(NID_SHELL, pAppContext, E_OBJ_NOT_FOUND, "Failed to find _AppContext.");
 
-       providerCount = pAppContext->GetProviderCount(appId);
+       providerCount = pAppContext->GetProviderCount();
 
        r = pAppContext->DestroyAppWidget(instanceId, false);
        SysTryReturnResult(NID_SHELL, !IsFailed(r), E_SYSTEM, "Failed to execute DestroyAppWidget.");