apply dynamic singleton pattern to internal classes and add retry code to AppWidgetMa...
[platform/framework/native/shell.git] / src / core / FShell_LockManagerProxy.cpp
index 20f1117..c4ea037 100644 (file)
 #include <unique_ptr.h>
 #include <FBaseErrors.h>
 #include <FBaseSysLog.h>
+#include <FBaseRt.h>
 #include <FIo_IpcClient.h>
 
 #include "FShell_LockManagerIpcMessages.h"
 #include "FShell_LockManagerProxy.h"
 
 using namespace Tizen::Base;
+using namespace Tizen::Io;
 using namespace Tizen::Shell;
 
+namespace
+{
+const char IPC_SERVER_NAME[] = "osp.shell.ipcserver.lockmanager";
+};
+
 namespace Tizen { namespace Shell
 {
 
+_LockManagerProxy* _LockManagerProxy::__pTheInstance = null;
+
 _LockManagerProxy::_LockManagerProxy(void)
        : __pIpcClient(null)
 {
@@ -44,20 +53,75 @@ _LockManagerProxy::~_LockManagerProxy(void)
 {
 }
 
+void
+_LockManagerProxy::InitSingleton(void)
+{
+       std::unique_ptr<_LockManagerProxy> pInst(new (std::nothrow) _LockManagerProxy());
+       SysTryReturnVoidResult(NID_SHELL, pInst, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
+
+       result r = pInst->Construct();
+       SysTryReturnVoidResult(NID_SHELL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
+
+       __pTheInstance = pInst.release();
+       std::atexit(DestroySingleton);
+}
+
+void
+_LockManagerProxy::DestroySingleton(void)
+{
+       delete __pTheInstance;
+}
+
+_LockManagerProxy*
+_LockManagerProxy::GetInstance(void)
+{
+       static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
+       if (__pTheInstance == null)
+       {
+               ClearLastResult();
+               pthread_once(&onceBlock, InitSingleton);
+               result r = GetLastResult();
+               if (IsFailed(r))
+               {
+                       onceBlock = PTHREAD_ONCE_INIT;
+               }
+       }
+       return __pTheInstance;
+}
+
 result
-_LockManagerProxy::Construct()
+_LockManagerProxy::Construct(void)
 {
-       __pIpcClient = new (std::nothrow) Tizen::Io::_IpcClient();
-       SysTryReturnResult(NID_APP, __pIpcClient != null, E_OUT_OF_MEMORY, "The memory is not sufficient.");
+       SysLog(NID_SHELL, "Enter.");
+
+       __pIpcClient = new (std::nothrow) _IpcClient();
+       SysTryReturnResult(NID_SHELL, __pIpcClient != null, E_OUT_OF_MEMORY, "_IpcClient creation failed.");
+
+       const int MAX_TRY_COUNT = 5;
+       const int TRY_SLEEP_TIME = 250;
+
+       int count = 0;
+       while (true)
+       {
+               result r = __pIpcClient->Construct(IPC_SERVER_NAME);
+               if (r == E_SUCCESS)
+               {
+                       SysLog(NID_APP, "Succeeded in connecting service(%s)", IPC_SERVER_NAME);
+                       return E_SUCCESS;
+               }
+
+               SysTryReturn(NID_APP, count < MAX_TRY_COUNT, E_SYSTEM, r, "[%s] Failed to connect service.(%s)", GetErrorMessage(r), IPC_SERVER_NAME);
 
-       result r = __pIpcClient->Construct("osp.shell.ipcserver.lockmanager");
-       SysTryReturnResult(NID_APP, !IsFailed(r), r, "_IpcClient constructing failed.");
+               count++;
+               Tizen::Base::Runtime::Thread::Sleep(TRY_SLEEP_TIME);
+       }
 
+       SysLog(NID_SHELL, "Exit.");
        return E_SUCCESS;
 }
 
 result
-_LockManagerProxy::Unlock()
+_LockManagerProxy::Unlock(void)
 {
       SysTryReturnResult(NID_APP, __pIpcClient != null, E_INVALID_STATE, "__pIpcClient instance must not be null.");