Merge "Update deprecated libprivilege-control API functions." into tizen
[platform/framework/native/appfw.git] / src / base / runtime / FBaseRt_SemaphoreImpl.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file        FBaseRt_SemaphoreImpl.cpp
19  * @brief       This is the implementation file for the _SemaphoreImpl class.
20  *
21  */
22
23 #include <semaphore.h>
24 #include <stdlib.h>
25 #include <errno.h>
26 #include <time.h>
27
28 #include "FBase_NativeError.h"
29 #include <FBaseSysLog.h>
30 #include "FBaseRt_SemaphoreImpl.h"
31
32 namespace Tizen { namespace Base { namespace Runtime
33 {
34
35 _SemaphoreImpl::_SemaphoreImpl(void)
36         : __pSemaphore(null)
37         , __name("")
38         , __count(0)
39 {
40
41 }
42
43 _SemaphoreImpl::~_SemaphoreImpl(void)
44 {
45         if (__pSemaphore != null)
46         {
47                 sem_destroy(__pSemaphore);
48                 free(__pSemaphore);
49
50                 __pSemaphore = null;
51         }
52 }
53
54 result
55 _SemaphoreImpl::Create(int count)
56 {
57         return Create(L"", count);
58 }
59
60 result
61 _SemaphoreImpl::Create(const Tizen::Base::String& name, int count)
62 {
63         int ret = 0;
64         result r = E_SUCCESS;
65         sem_t* pSemaphore = null;
66
67         SysTryReturnResult(NID_BASE_RT, count >= 0, E_INVALID_ARG,
68                                 "The count(%d) MUST be greater than or equal to 0.", count);
69
70         pSemaphore = (sem_t*) malloc(sizeof(sem_t));
71         SysTryReturnResult(NID_BASE_RT, pSemaphore != null, E_OUT_OF_MEMORY,
72                                 "Semaphore memory allocation failed.");
73
74         ret = sem_init(pSemaphore, 0, count);
75         SysTryCatch(NID_BASE_RT, ret == 0, r = E_SYSTEM, E_SYSTEM,
76                                    "[E_SYSTEM] Semaphore intialization failed : [%s]", __ConvertNativeErrorToMessage(errno));
77
78         if (name.GetLength() > 0)
79         {
80                 __name = name;
81         }
82
83         __count = count;
84         __pSemaphore = pSemaphore;
85
86         return E_SUCCESS;
87
88 CATCH:
89         free(pSemaphore);
90
91         return r;
92 }
93
94 result
95 _SemaphoreImpl::Acquire(long timeout)
96 {
97         SysTryReturnResult(NID_BASE_RT, __pSemaphore != null, E_INVALID_STATE,
98                                 "Sempahore is not initialized.");
99
100         while (1)
101         {
102                 int rval = 0;
103
104                 if (timeout == (long) INFINITE)
105                 {
106                         rval = sem_wait((sem_t*) __pSemaphore);
107                 }
108                 else
109                 {
110                         struct timespec tm;
111
112                         rval = clock_gettime(CLOCK_REALTIME, &tm);
113                         SysTryReturn(NID_BASE_RT, rval == 0, E_SYSTEM, E_SYSTEM,
114                                                         "[%s] Sempahore acquire timeout setting failed.", __ConvertNativeErrorToMessage(errno));
115
116                         tm.tv_sec += timeout / 1000;            // convert ms to s
117                         tm.tv_nsec += (timeout % 1000) * (1000 * 1000); // convert ms to ns
118
119                         rval = sem_timedwait((sem_t*) __pSemaphore, &tm);
120                 }
121
122                 if (rval == 0)
123                 {
124                         return E_SUCCESS;
125                 }
126
127                 switch (errno)
128                 {
129                         case EINTR:
130                                 continue;       // interrupted due to some signal, continue wait
131
132                         case ETIMEDOUT:
133                                 SysLogException(NID_BASE_RT, E_TIMEOUT, "[E_TIMEOUT] Semaphore acquire timedout");
134                                 return E_TIMEOUT;
135
136                         default:
137                                 SysLogException(NID_BASE_RT, E_SYSTEM, "[E_SYSTEM] Semaphore acquire failed due to system error.");
138                                 return E_SYSTEM;
139                 }
140         }
141 }
142
143 result
144 _SemaphoreImpl::TryToAcquire(void)
145 {
146         int rval = 0;
147
148         while (true)
149         {
150                 rval = sem_trywait((sem_t*) __pSemaphore);
151
152                 if (rval == 0)
153                 {
154                         return E_SUCCESS;
155                 }
156
157                 switch (errno)
158                 {
159                         case EINTR:
160                                 continue;       // interrupted due to some signal, continue wait
161
162                         case EAGAIN:
163                                 SysLogException(NID_BASE_RT, E_OBJECT_LOCKED, "[E_OBJECT_LOCKED] Semaphore is already locked");
164                                 return E_OBJECT_LOCKED;
165
166                         default:
167                                 SysLogException(NID_BASE_RT, E_SYSTEM, "[E_SYSTEM] Semaphore acquire failed : [%s]", __ConvertNativeErrorToMessage(errno));
168                                 return E_SYSTEM;
169                 }
170         }
171
172 }
173 result
174 _SemaphoreImpl::Release(void)
175 {
176         SysTryReturnResult(NID_BASE_RT, __pSemaphore != null, E_INVALID_STATE,
177                                 "Sempahore is not initialized.");
178
179         int rval = sem_post((sem_t*) __pSemaphore);
180         SysTryReturnResult(NID_BASE_RT, rval == 0, E_SYSTEM,
181                                         "Sempahore release failed : [%s]", __ConvertNativeErrorToMessage(errno));
182
183         return E_SUCCESS;
184 }
185
186 } } } // Tizen::Runtime