From 7cd224983f0d9f52cf9d2f9144bf2078839be21e Mon Sep 17 00:00:00 2001 From: "kyeongwoo.lee" Date: Tue, 13 Aug 2013 17:15:52 +0900 Subject: [PATCH] Fixed memory leaks. Change-Id: Ibb6c241296d581ff424b41243257fef8c89f8621 --- inc/FShell_AppContext.h | 2 +- inc/FShell_AppWidgetManagerService.h | 5 +- src/FShell_AppContext.cpp | 20 +++++++- src/FShell_AppWidgetManagerService.cpp | 68 +++++++++++++++++++++++--- 4 files changed, 85 insertions(+), 10 deletions(-) diff --git a/inc/FShell_AppContext.h b/inc/FShell_AppContext.h index d888b41..f4df21d 100644 --- a/inc/FShell_AppContext.h +++ b/inc/FShell_AppContext.h @@ -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); diff --git a/inc/FShell_AppWidgetManagerService.h b/inc/FShell_AppWidgetManagerService.h index be4f5ca..28b78f2 100644 --- a/inc/FShell_AppWidgetManagerService.h +++ b/inc/FShell_AppWidgetManagerService.h @@ -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; diff --git a/src/FShell_AppContext.cpp b/src/FShell_AppContext.cpp index 19d3ad0..5c5f942 100644 --- a/src/FShell_AppContext.cpp +++ b/src/FShell_AppContext.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -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* 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(); } diff --git a/src/FShell_AppWidgetManagerService.cpp b/src/FShell_AppWidgetManagerService.cpp index 0b1a999..092decf 100644 --- a/src/FShell_AppWidgetManagerService.cpp +++ b/src/FShell_AppWidgetManagerService.cpp @@ -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* 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 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."); -- 2.34.1