1 /* 2 * Copyright (C) Texas Instruments - http://www.ti.com/ 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 19 #include "Semaphore.h" 20 #include "ErrorUtils.h" 21 #include <utils/Log.h> 22 #include <time.h> 23 24 namespace Ti { 25 namespace Utils { 26 27 /** 28 @brief Constructor for the semaphore class 29 30 @param none 31 @return none 32 */ 33 Semaphore::Semaphore() 34 { 35 ///Initialize the semaphore to NULL 36 mSemaphore = NULL; 37 } 38 39 /** 40 @brief Destructor of the semaphore class 41 42 @param none 43 @return none 44 45 */ 46 Semaphore::~Semaphore() 47 { 48 Release(); 49 } 50 51 /** 52 @brief: Releases semaphore 53 54 @param count >=0 55 @return NO_ERROR On Success 56 @return One of the android error codes based on semaphore de-initialization 57 */ 58 59 status_t Semaphore::Release() 60 { 61 int status = 0; 62 63 ///Destroy only if the semaphore has been created 64 if(mSemaphore) 65 { 66 status = sem_destroy(mSemaphore); 67 68 free(mSemaphore); 69 70 mSemaphore = NULL; 71 } 72 73 ///Initialize the semaphore and return the status 74 return ErrorUtils::posixToAndroidError(status); 75 76 } 77 78 /** 79 @brief Create the semaphore with initial count value 80 81 @param count >=0 82 @return NO_ERROR On Success 83 @return NO_MEMORY If unable to allocate memory for the semaphore 84 @return BAD_VALUE If an invalid count value is passed (<0) 85 @return One of the android error codes based on semaphore initialization 86 */ 87 88 status_t Semaphore::Create(int count) 89 { 90 status_t ret = NO_ERROR; 91 92 ///count cannot be less than zero 93 if(count<0) 94 { 95 return BAD_VALUE; 96 } 97 98 ret = Release(); 99 if ( NO_ERROR != ret ) 100 { 101 return ret; 102 } 103 104 ///allocate memory for the semaphore 105 mSemaphore = (sem_t*)malloc(sizeof(sem_t)) ; 106 107 ///if memory is unavailable, return error 108 if(!mSemaphore) 109 { 110 return NO_MEMORY; 111 } 112 113 ///Initialize the semaphore and return the status 114 return ErrorUtils::posixToAndroidError(sem_init(mSemaphore, 0x00, count)); 115 116 } 117 118 /** 119 @brief Wait operation 120 121 @param none 122 @return BAD_VALUE if the semaphore is not initialized 123 @return NO_ERROR On success 124 @return One of the android error codes based on semaphore wait operation 125 */ 126 status_t Semaphore::Wait() 127 { 128 ///semaphore should have been created first 129 if(!mSemaphore) 130 { 131 return BAD_VALUE; 132 } 133 134 ///Wait and return the status after signalling 135 return ErrorUtils::posixToAndroidError(sem_wait(mSemaphore)); 136 137 138 } 139 140 141 /** 142 @brief Signal operation 143 144 @param none 145 @return BAD_VALUE if the semaphore is not initialized 146 @return NO_ERROR On success 147 @return One of the android error codes based on semaphore signal operation 148 */ 149 150 status_t Semaphore::Signal() 151 { 152 ///semaphore should have been created first 153 if(!mSemaphore) 154 { 155 return BAD_VALUE; 156 } 157 158 ///Post to the semaphore 159 return ErrorUtils::posixToAndroidError(sem_post(mSemaphore)); 160 161 } 162 163 /** 164 @brief Current semaphore count 165 166 @param none 167 @return Current count value of the semaphore 168 */ 169 int Semaphore::Count() 170 { 171 int val; 172 173 ///semaphore should have been created first 174 if(!mSemaphore) 175 { 176 return BAD_VALUE; 177 } 178 179 ///get the value of the semaphore 180 sem_getvalue(mSemaphore, &val); 181 182 return val; 183 } 184 185 /** 186 @brief Wait operation with a timeout 187 188 @param timeoutMicroSecs The timeout period in micro seconds 189 @return BAD_VALUE if the semaphore is not initialized 190 @return NO_ERROR On success 191 @return One of the android error codes based on semaphore wait operation 192 */ 193 194 status_t Semaphore::WaitTimeout(int timeoutMicroSecs) 195 { 196 status_t ret = NO_ERROR; 197 198 struct timespec timeSpec; 199 struct timeval currentTime; 200 201 ///semaphore should have been created first 202 if( NULL == mSemaphore) 203 { 204 ret = BAD_VALUE; 205 } 206 207 if ( NO_ERROR == ret ) 208 { 209 210 ///setup the timeout values - timeout is specified in seconds and nanoseconds 211 gettimeofday(¤tTime, NULL); 212 timeSpec.tv_sec = currentTime.tv_sec; 213 timeSpec.tv_nsec = currentTime.tv_usec * 1000; 214 timeSpec.tv_sec += ( timeoutMicroSecs / 1000000 ); 215 timeSpec.tv_nsec += ( timeoutMicroSecs % 1000000) * 1000; 216 217 ///Wait for the timeout or signal and return the result based on whichever event occurred first 218 ret = sem_timedwait(mSemaphore, &timeSpec); 219 } 220 221 if ( NO_ERROR != ret ) 222 { 223 Signal(); 224 Create(0); 225 } 226 227 return ret; 228 } 229 230 231 } // namespace Utils 232 } // namespace Ti 233