sync with tizen_2.0
[platform/framework/native/appfw.git] / src / base / runtime / FBaseRt_SemaphoreImpl.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_SemaphoreImpl.cpp
20  * @brief       This is the implementation file for the _SemaphoreImpl class.
21  *
22  */
23
24 #include <semaphore.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <time.h>
28
29 #include "FBase_NativeError.h"
30 #include <FBaseSysLog.h>
31 #include "FBaseRt_SemaphoreImpl.h"
32
33 namespace Tizen { namespace Base { namespace Runtime
34 {
35
36 _SemaphoreImpl::_SemaphoreImpl(void)
37         : __pSemaphore(null)
38         , __name("")
39         , __count(0)
40 {
41
42 }
43
44 _SemaphoreImpl::~_SemaphoreImpl(void)
45 {
46         if (__pSemaphore != null)
47         {
48                 sem_destroy(__pSemaphore);
49                 free(__pSemaphore);
50
51                 __pSemaphore = null;
52         }
53 }
54
55 result
56 _SemaphoreImpl::Create(int count)
57 {
58         return Create(L"", count);
59 }
60
61 result
62 _SemaphoreImpl::Create(const Tizen::Base::String& name, int count)
63 {
64         int ret = 0;
65         result r = E_SUCCESS;
66         sem_t* pSemaphore = null;
67
68         SysTryReturnResult(NID_BASE_RT, count >= 0, E_INVALID_ARG,
69                                 "The count(%d) MUST be greater than or equal to 0.", count);
70
71         pSemaphore = (sem_t*) malloc(sizeof(sem_t));
72         SysTryReturnResult(NID_BASE_RT, pSemaphore != null, E_OUT_OF_MEMORY,
73                                 "Semaphore memory allocation failed.");
74
75         ret = sem_init(pSemaphore, 0, count);
76         SysTryCatch(NID_BASE_RT, ret == 0, r = E_SYSTEM, E_SYSTEM,
77                                    "[E_SYSTEM] Semaphore intialization failed : [%s]", __ConvertNativeErrorToMessage(errno));
78
79         if (name.GetLength() > 0)
80         {
81                 __name = name;
82         }
83
84         __count = count;
85         __pSemaphore = pSemaphore;
86
87         return E_SUCCESS;
88
89 CATCH:
90         free(pSemaphore);
91
92         return r;
93 }
94
95 result
96 _SemaphoreImpl::Acquire(long timeout)
97 {
98         SysTryReturnResult(NID_BASE_RT, __pSemaphore != null, E_INVALID_STATE,
99                                 "Sempahore is not initialized.");
100
101         while (1)
102         {
103                 int rval = 0;
104
105                 if (timeout == (long) INFINITE)
106                 {
107                         rval = sem_wait((sem_t*) __pSemaphore);
108                 }
109                 else
110                 {
111                         struct timespec tm;
112
113                         rval = clock_gettime(CLOCK_REALTIME, &tm);
114                         SysTryReturn(NID_BASE_RT, rval == 0, E_SYSTEM, E_SYSTEM,
115                                                         "[%s] Sempahore acquire timeout setting failed.", __ConvertNativeErrorToMessage(errno));
116
117                         tm.tv_sec += timeout / 1000;            // convert ms to s
118                         tm.tv_nsec += (timeout % 1000) * (1000 * 1000); // convert ms to ns
119
120                         rval = sem_timedwait((sem_t*) __pSemaphore, &tm);
121                 }
122
123                 if (rval == 0)
124                 {
125                         return E_SUCCESS;
126                 }
127
128                 switch (errno)
129                 {
130                         case EINTR:
131                                 continue;       // interrupted due to some signal, continue wait
132
133                         case ETIMEDOUT:
134                                 SysLogException(NID_BASE_RT, E_TIMEOUT, "[E_TIMEOUT] Semaphore acquire timedout");
135                                 return E_TIMEOUT;
136
137                         default:
138                                 SysLogException(NID_BASE_RT, E_SYSTEM, "[E_SYSTEM] Semaphore acquire failed due to system error.");
139                                 return E_SYSTEM;
140                 }
141         }
142 }
143
144 result
145 _SemaphoreImpl::TryToAcquire(void)
146 {
147         int rval = 0;
148
149         while (true)
150         {
151                 rval = sem_trywait((sem_t*) __pSemaphore);
152
153                 if (rval == 0)
154                 {
155                         return E_SUCCESS;
156                 }
157
158                 switch (errno)
159                 {
160                         case EINTR:
161                                 continue;       // interrupted due to some signal, continue wait
162
163                         case EAGAIN:
164                                 SysLogException(NID_BASE_RT, E_OBJECT_LOCKED, "[E_OBJECT_LOCKED] Semaphore is already locked");
165                                 return E_OBJECT_LOCKED;
166
167                         default:
168                                 SysLogException(NID_BASE_RT, E_SYSTEM, "[E_SYSTEM] Semaphore acquire failed : [%s]", __ConvertNativeErrorToMessage(errno));
169                                 return E_SYSTEM;
170                 }
171         }
172
173 }
174 result
175 _SemaphoreImpl::Release(void)
176 {
177         SysTryReturnResult(NID_BASE_RT, __pSemaphore != null, E_INVALID_STATE,
178                                 "Sempahore is not initialized.");
179
180         int rval = sem_post((sem_t*) __pSemaphore);
181         SysTryReturnResult(NID_BASE_RT, rval == 0, E_SYSTEM,
182                                         "Sempahore release failed : [%s]", __ConvertNativeErrorToMessage(errno));
183
184         return E_SUCCESS;
185 }
186
187 } } } // Tizen::Runtime