1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 25 #include "system.h" 26 27 #include <osl/semaphor.h> 28 #include <osl/diagnose.h> 29 30 #ifndef OSL_USE_SYS_V_SEMAPHORE 31 32 /* This is the (default) POSIX thread-local semaphore variant */ 33 34 /* 35 Implemetation notes: 36 The void* represented by oslSemaphore is used 37 as a pointer to an sem_t struct 38 */ 39 40 /*****************************************************************************/ 41 /* osl_createSemaphore */ 42 /*****************************************************************************/ 43 44 oslSemaphore SAL_CALL osl_createSemaphore(sal_uInt32 initialCount) 45 { 46 int ret = 0; 47 oslSemaphore Semaphore; 48 49 Semaphore= malloc(sizeof(sem_t)); 50 51 OSL_ASSERT(Semaphore); /* ptr valid? */ 52 53 if ( Semaphore == 0 ) 54 { 55 return 0; 56 } 57 58 /* unnamed semaphore, not shared between processes */ 59 60 ret= sem_init((sem_t*)Semaphore, 0, initialCount); 61 62 /* create failed? */ 63 if (ret != 0) 64 { 65 OSL_TRACE("osl_createSemaphore failed. Errno: %d; %s\n", 66 errno, 67 strerror(errno)); 68 69 free(Semaphore); 70 Semaphore = NULL; 71 } 72 73 return Semaphore; 74 } 75 76 /*****************************************************************************/ 77 /* osl_destroySemaphore */ 78 /*****************************************************************************/ 79 void SAL_CALL osl_destroySemaphore(oslSemaphore Semaphore) 80 { 81 if(Semaphore) /* ptr valid? */ 82 { 83 sem_destroy((sem_t*)Semaphore); 84 free(Semaphore); 85 } 86 } 87 88 /*****************************************************************************/ 89 /* osl_acquireSemaphore */ 90 /*****************************************************************************/ 91 sal_Bool SAL_CALL osl_acquireSemaphore(oslSemaphore Semaphore) { 92 93 OSL_ASSERT(Semaphore != 0); /* abort in debug mode */ 94 95 if (Semaphore != 0) /* be tolerant in release mode */ 96 { 97 return (sem_wait((sem_t*)Semaphore) == 0); 98 } 99 100 return sal_False; 101 } 102 103 /*****************************************************************************/ 104 /* osl_tryToAcquireSemaphore */ 105 /*****************************************************************************/ 106 sal_Bool SAL_CALL osl_tryToAcquireSemaphore(oslSemaphore Semaphore) { 107 108 OSL_ASSERT(Semaphore != 0); /* abort in debug mode */ 109 if (Semaphore != 0) /* be tolerant in release mode */ 110 { 111 return (sem_trywait((sem_t*)Semaphore) == 0); 112 } 113 114 return sal_False; 115 } 116 117 /*****************************************************************************/ 118 /* osl_releaseSemaphore */ 119 /*****************************************************************************/ 120 sal_Bool SAL_CALL osl_releaseSemaphore(oslSemaphore Semaphore) { 121 122 OSL_ASSERT(Semaphore != 0); /* abort in debug mode */ 123 124 if (Semaphore != 0) /* be tolerant in release mode */ 125 { 126 return (sem_post((sem_t*)Semaphore) == 0); 127 } 128 129 return sal_False; 130 } 131 132 #else /* OSL_USE_SYS_V_SEMAPHORE */ 133 134 /*******************************************************************************/ 135 136 /* This is the SYS V private semaphore variant */ 137 138 /* 139 Implemetation notes: 140 The void* represented by oslSemaphore is used 141 as a pointer to an osl_TSemImpl struct 142 */ 143 144 145 #if defined(NETBSD) 146 union semun { 147 int val; /* value for SETVAL */ 148 struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ 149 u_short *array; /* array for GETALL & SETALL */ 150 }; 151 #endif 152 153 typedef struct _osl_TSemImpl 154 { 155 int m_Id; 156 157 } osl_TSemImpl; 158 159 /*****************************************************************************/ 160 /* osl_createSemaphore */ 161 /*****************************************************************************/ 162 oslSemaphore SAL_CALL osl_createSemaphore(sal_uInt32 initialCount) 163 { 164 union semun arg; 165 166 oslSemaphore Semaphore; 167 osl_TSemImpl* pSem; 168 169 Semaphore= malloc(sizeof(osl_TSemImpl)); 170 OSL_POSTCOND(Semaphore, "malloc failed\n"); /* ptr valid? */ 171 172 pSem= (osl_TSemImpl*)Semaphore; 173 174 175 /* unnamed (private) semaphore */ 176 177 pSem->m_Id= semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT); 178 179 180 /* create failed? */ 181 if (pSem->m_Id < 0) 182 { 183 OSL_TRACE("osl_createSemaphore failed (semget). Errno: %d; %s\n", 184 errno, 185 strerror(errno)); 186 187 free(Semaphore); 188 return 0; 189 } 190 191 /* set initial count */ 192 193 arg.val= initialCount; 194 195 if(semctl(pSem->m_Id, 0, SETVAL, arg) < 0) 196 { 197 OSL_TRACE("osl_createSemaphore failed (semctl(SETVAL)). Errno: %d; %s\n", 198 errno, 199 strerror(errno)); 200 201 if(semctl(pSem->m_Id, 0, IPC_RMID, arg) < 0) 202 { 203 OSL_TRACE("semctl(IPC_RMID) failed. Errno: %d; %s\n", errno, strerror(errno)); 204 } 205 206 free(Semaphore); 207 return 0; 208 } 209 210 211 return Semaphore; 212 } 213 214 /*****************************************************************************/ 215 /* osl_destroySemaphore */ 216 /*****************************************************************************/ 217 void SAL_CALL osl_destroySemaphore(oslSemaphore Semaphore) { 218 219 if(Semaphore) /* ptr valid? */ 220 { 221 union semun arg; 222 223 osl_TSemImpl* pSem= (osl_TSemImpl*)Semaphore; 224 225 if(semctl(pSem->m_Id, 0, IPC_RMID, arg) < 0) 226 227 { 228 OSL_TRACE("osl_destroySemaphore failed. (semctl(IPC_RMID)). Errno: %d; %s\n", 229 errno, 230 strerror(errno)); 231 } 232 233 free(Semaphore); 234 } 235 } 236 237 /*****************************************************************************/ 238 /* osl_acquireSemaphore */ 239 /*****************************************************************************/ 240 sal_Bool SAL_CALL osl_acquireSemaphore(oslSemaphore Semaphore) { 241 242 /* abort in debug mode */ 243 OSL_PRECOND(Semaphore != 0, "Semaphore not created\n"); 244 245 246 if (Semaphore != 0) /* be tolerant in release mode */ 247 { 248 struct sembuf op; 249 osl_TSemImpl* pSem= (osl_TSemImpl*)Semaphore; 250 251 op.sem_num= 0; 252 op.sem_op= -1; 253 op.sem_flg= SEM_UNDO; 254 255 return semop(pSem->m_Id, &op, 1) >= 0; 256 257 } 258 259 return sal_False; 260 } 261 262 /*****************************************************************************/ 263 /* osl_tryToAcquireSemaphore */ 264 /*****************************************************************************/ 265 sal_Bool SAL_CALL osl_tryToAcquireSemaphore(oslSemaphore Semaphore) { 266 267 /* abort in debug mode */ 268 OSL_PRECOND(Semaphore != 0, "Semaphore not created\n"); 269 270 if (Semaphore != 0) /* be tolerant in release mode */ 271 { 272 struct sembuf op; 273 osl_TSemImpl* pSem= (osl_TSemImpl*)Semaphore; 274 275 op.sem_num= 0; 276 op.sem_op= -1; 277 op.sem_flg= SEM_UNDO | IPC_NOWAIT; 278 279 return semop(pSem->m_Id, &op, 1) >= 0; 280 } 281 282 return sal_False; 283 } 284 285 /*****************************************************************************/ 286 /* osl_releaseSemaphore */ 287 /*****************************************************************************/ 288 sal_Bool SAL_CALL osl_releaseSemaphore(oslSemaphore Semaphore) 289 { 290 291 /* abort in debug mode */ 292 OSL_PRECOND(Semaphore != 0, "Semaphore not created\n"); 293 294 if (Semaphore != 0) /* be tolerant in release mode */ 295 { 296 struct sembuf op; 297 osl_TSemImpl* pSem= (osl_TSemImpl*)Semaphore; 298 299 op.sem_num= 0; 300 op.sem_op= 1; 301 op.sem_flg= SEM_UNDO; 302 303 return semop(pSem->m_Id, &op, 1) >= 0; 304 } 305 306 return sal_False; 307 } 308 309 #endif /* OSL_USE_SYS_V_SEMAPHORE */ 310 311