sync with master
[platform/framework/native/appfw.git] / src / base / runtime / FBaseRt_MutexImpl.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 /**
19  * @file        FBaseRt_MutexImpl.cpp
20  * @brief       This is the implementation file for the _MutexImpl class.
21  *
22  */
23
24 #include <pthread.h>
25 #include <stdlib.h>
26 #include <errno.h>
27
28 #include <FBaseSysLog.h>
29 #include "FBase_NativeError.h"
30 #include "FBaseRt_MutexImpl.h"
31
32 namespace Tizen { namespace Base { namespace Runtime
33 {
34
35 _MutexImpl::_MutexImpl(void)
36         : __pMutex(null)
37 {
38
39 }
40
41 _MutexImpl::~_MutexImpl(void)
42 {
43         if (__pMutex != null)
44         {
45                 pthread_mutex_destroy(__pMutex);
46                 free(__pMutex);
47                 __pMutex = null;
48         }
49 }
50
51 result
52 _MutexImpl::Create(void)
53 {
54         return Create(L"");
55 }
56
57 result
58 _MutexImpl::CreateNonRecursiveMutex(void)
59 {
60         result r = E_SUCCESS;
61         pthread_mutex_t* pMutex = null;
62
63         int ret = -1;
64         pthread_mutexattr_t mutexAttr;
65         // create mutex
66         pMutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
67         SysTryReturnResult(NID_BASE_RT, pMutex != null, E_OUT_OF_MEMORY,
68                                           "Mutex memory allocation failed.")
69
70         // set mutex attributes
71         pthread_mutexattr_init(&mutexAttr);
72         pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_PRIVATE);
73         pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_ERRORCHECK_NP);
74
75         // intialize the mutex
76         ret = pthread_mutex_init(pMutex, &mutexAttr);
77         SysTryCatch(NID_BASE_RT, ret == 0, r = E_SYSTEM, E_SYSTEM,
78                            "[%s] Mutex intialization failed.", __ConvertNativeErrorToMessage(ret));
79
80         // destroy the attributes
81         pthread_mutexattr_destroy(&mutexAttr);
82
83         __pMutex = pMutex;
84
85         return E_SUCCESS;
86
87 CATCH:
88         if (pMutex != null)
89         {
90                 free(pMutex);
91         }
92
93         return r;
94
95 }
96
97
98 result
99 _MutexImpl::Create(const Tizen::Base::String& name)
100 {
101         result r = E_SUCCESS;
102         pthread_mutex_t* pMutex = null;
103
104         int ret = -1;
105         pthread_mutexattr_t mutexAttr;
106         // create mutex
107         pMutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
108         SysTryReturnResult(NID_BASE_RT, pMutex != null, E_OUT_OF_MEMORY,
109                                           "Mutex memory allocation failed.")
110
111         // set mutex attributes
112         pthread_mutexattr_init(&mutexAttr);
113         pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_PRIVATE);
114         pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE_NP);
115
116         // intialize the mutex
117         ret = pthread_mutex_init(pMutex, &mutexAttr);
118         SysTryCatch(NID_BASE_RT, ret == 0, r = E_SYSTEM, E_SYSTEM,
119                            "[%s] Mutex intialization failed.", __ConvertNativeErrorToMessage(ret));
120
121         // destroy the attributes
122         pthread_mutexattr_destroy(&mutexAttr);
123
124         __name = name;
125         __pMutex = pMutex;
126
127         return E_SUCCESS;
128
129 CATCH:
130         if (pMutex != null)
131         {
132                 free(pMutex);
133         }
134
135         return r;
136 }
137
138 result
139 _MutexImpl::Acquire(void)
140 {
141         return Acquire(INFINITE);
142 }
143
144 result
145 _MutexImpl::Acquire(long timeout)
146 {
147         SysTryReturnResult(NID_BASE_RT, __pMutex != null, E_INVALID_STATE, "Mutex is not initialized.");
148
149         if (timeout == (long) INFINITE)
150         {
151                 int rval = pthread_mutex_lock((pthread_mutex_t*) __pMutex);
152                 SysTryReturnResult(NID_BASE_RT, rval == 0, E_SYSTEM, "[%s] Mutex acquire failed.", __ConvertNativeErrorToMessage(rval));
153         }
154         else
155         {
156                 struct timespec tm;
157
158                 int rval = clock_gettime(CLOCK_REALTIME, &tm);
159                 SysTryReturn(NID_BASE_RT, rval == 0, E_SYSTEM, E_SYSTEM,
160                                                 "[%s] Mutex acquire timeout setting failed.", __ConvertNativeErrorToMessage(errno));
161
162                 tm.tv_sec += timeout / 1000;            // convert ms to s
163                 tm.tv_nsec += (timeout % 1000) * (1000 * 1000); // convert ms to ns
164
165                 rval = pthread_mutex_timedlock((pthread_mutex_t*) __pMutex, &tm);
166                 if (rval == 0)
167                 {
168                         return E_SUCCESS;
169                 }
170
171                 switch (rval)
172                 {
173                         case ETIMEDOUT:
174                                 SysLogException(NID_BASE_RT, E_SYSTEM, "[E_SYSTEM] Mutex acquire failed due to timedout");
175                                 return E_SYSTEM;
176                         default:
177                                 SysLogException(NID_BASE_RT, E_SYSTEM, "[E_SYSTEM] Mutex acquire failed : [%s].", __ConvertNativeErrorToMessage(rval));
178                                 return E_SYSTEM;
179                 }
180         }
181
182         return E_SUCCESS;
183 }
184
185 result
186 _MutexImpl::TryToAcquire(void)
187 {
188         SysTryReturnResult(NID_BASE_RT, __pMutex != null, E_INVALID_STATE, "Mutex is not initialized.");
189
190         int rval = pthread_mutex_trylock((pthread_mutex_t*) __pMutex);
191         if (rval == 0)
192         {
193                 return E_SUCCESS;
194         }
195
196         switch (rval)
197         {
198                 case EBUSY:
199                         SysLogException(NID_BASE_RT, E_OBJECT_LOCKED, "[E_OBJECT_LOCKED] Mutex acquire failed.");
200                         return E_OBJECT_LOCKED;
201                 default:
202                         SysLogException(NID_BASE_RT, E_SYSTEM, "[E_SYSTEM] Mutex acquire failed : [%s].", __ConvertNativeErrorToMessage(rval));
203                         return E_SYSTEM;
204         }
205 }
206
207 result
208 _MutexImpl::Release(void)
209 {
210         SysTryReturnResult(NID_BASE_RT, __pMutex != null, E_INVALID_STATE, "Mutex is not initialized.");
211
212         int rval = pthread_mutex_unlock((pthread_mutex_t*) __pMutex);
213         SysTryReturnResult(NID_BASE_RT, rval == 0, E_SYSTEM,
214                                         "Mutex release failed : [%s]", __ConvertNativeErrorToMessage(rval));
215
216         return E_SUCCESS;
217 }
218
219 } } } // Tizen::Runtime