Fixed update instance
[framework/osp/social.git] / src / FScl_ContactDbConnector.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 /**
18  * @file                FScl_AddressbookUtil.cpp
19  * @brief               This is the implementation for _AddressbookUtil class.
20  *
21  * This file contains definitions of @e _AddressbookUtil class.
22  */
23
24 #include <unique_ptr.h>
25 #include <pthread.h>
26 #include <FBaseSysLog.h>
27 #include <FSysSystemTime.h>
28 #include "FScl_ContactDbConnector.h"
29
30 namespace Tizen { namespace Social
31 {
32
33 __thread bool isConnected = false;
34 pthread_key_t tlsKey = 0;
35 _ContactDbConnector* _ContactDbConnector::__pInstance = null;
36
37 _ContactDbConnector::_ContactDbConnector(void)
38 {
39 }
40
41 _ContactDbConnector::~_ContactDbConnector(void)
42 {
43 }
44
45 void 
46 _ContactDbConnector::OnThreadExit(void *pValue)
47 {
48         _ContactDbConnector* pInstance = static_cast<_ContactDbConnector*>(pValue);
49
50         if (pInstance != null)
51         {
52                 pInstance->Disconnect();
53         }
54
55         pthread_setspecific(tlsKey, NULL);
56 }
57
58 result
59 _ContactDbConnector::Connect(void)
60 {
61         long long startTicks = 0;
62         long long endTicks = 0;
63
64         System::SystemTime::GetTicks(startTicks);
65
66         int ret = contacts_connect_with_flags(CONTACTS_CONNECT_FLAG_RETRY);
67
68         System::SystemTime::GetTicks(endTicks);
69
70         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
71         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_IPC_NOT_AVALIABLE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred. Contact server is not available. Elapsed time : %lld", GetErrorMessage(E_SYSTEM), endTicks - startTicks);
72         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
73
74         pthread_setspecific(tlsKey, this);
75
76         return E_SUCCESS;
77 }
78
79 result
80 _ContactDbConnector::Disconnect(void)
81 {
82         int ret = contacts_disconnect2();
83         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
84         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
85
86         return E_SUCCESS;
87 }
88
89 result
90 _ContactDbConnector::EnsureDbConnection(void)
91 {
92         if (!isConnected)
93         {
94                 _ContactDbConnector* pInstance = GetInstance();
95                 SysTryReturn(NID_SCL, pInstance != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
96
97                 result r = pInstance->Connect();
98                 SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
99
100                 isConnected = true;
101         }
102
103         return E_SUCCESS;
104 }
105
106 void
107 _ContactDbConnector::InitContactDbConnector(void)
108 {
109         std::unique_ptr<_ContactDbConnector> pInstance(new (std::nothrow) _ContactDbConnector());
110         SysTryReturnVoidResult(NID_SCL, pInstance, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
111
112         __pInstance = pInstance.release();
113
114         pthread_key_create(&tlsKey, OnThreadExit);
115
116         std::atexit(DestroyContactDbConnector);
117 }
118
119 void
120 _ContactDbConnector::DestroyContactDbConnector(void)
121 {
122         delete __pInstance;
123         __pInstance = null;
124 }
125
126 _ContactDbConnector*
127 _ContactDbConnector::GetInstance(void)
128 {
129         static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
130
131         if (__pInstance == null)
132         {
133                 ClearLastResult();
134
135                 pthread_once(&onceBlock, InitContactDbConnector);
136
137                 result r = GetLastResult();
138
139                 if (IsFailed(r))
140                 {
141                         onceBlock = PTHREAD_ONCE_INIT;
142                 }
143         }
144
145         return __pInstance;
146 }
147
148 }}  // Tizen::Social