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