123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- /*
- * Copyright (c) 2009-2011 Nokia Corporation and/or its subsidiary(-ies).
- * All rights reserved.
- * This component and the accompanying materials are made available
- * under the terms of the License "Eclipse Public License v1.0"
- * which accompanies this distribution, and is available
- * at the URL "http://www.eclipse.org/legal/epl-v10.html".
- *
- * Initial Contributors:
- * Nokia Corporation - initial contribution.
- *
- * Contributors:
- *
- * Description:
- *
- */
- #include "sema.h"
- #include "log.h"
- // OS specific headers
- #ifdef WIN32
- #include <windows.h>
- #include <tlhelp32.h>
- #else
- #include <semaphore.h>
- #include <sys/types.h>
- #include <signal.h>
- #include <fcntl.h>
- #include <time.h>
- #endif
- #include <unistd.h>
- void sema_create(sbs_semaphore *s)
- {
- #ifdef WIN32
- s->handle = CreateSemaphore(NULL, 1, 1, s->name);
- if (s->handle)
- CloseHandle(s->handle);
- else
- error("unable to create semaphore %s", s->name);
- #else
- s->handle = sem_open(s->name, O_CREAT | O_EXCL, 0644, 1);
-
- if (s->handle == SEM_FAILED)
- {
- sem_close(s->handle);
- error("unable to create semaphore %s", s->name);
- }
- sem_close(s->handle);
- #endif
- }
- void sema_destroy(sbs_semaphore *s)
- {
- #ifdef WIN32
- /* can't destroy a windows semaphore... */
- #else
- if (sem_unlink(s->name) != 0)
- error("unable to unlink semaphore", s->name);
- #endif
- }
- int sema_wait(sbs_semaphore *s)
- {
- /* try and open the semaphore now */
- #ifdef WIN32
- s->handle = CreateSemaphore(NULL, 1, 1, s->name);
- if (!s->handle)
- {
- error("unable to open semaphore %s", s->name);
- return -2;
- }
- #else
- struct timespec tmout;
-
- s->handle = sem_open(s->name, 0);
-
- if (s->handle == SEM_FAILED)
- {
- sem_close(s->handle);
- error("unable to open semaphore %s\n", s->name);
- return -2;
- }
- #endif
-
- /* wait for the semaphore to be free [timeout if it takes too long] */
- int timedOutFlag = 0;
- #ifdef WIN32
- timedOutFlag = (WaitForSingleObject(s->handle, s->timeout) != WAIT_OBJECT_0);
- #else
- int semcount = 0;
- sem_getvalue(s->handle, &semcount);
- debug("sema: count before wait: %d\n", semcount);
- debug("sema: timeout: %d\n", s->timeout);
- if (clock_gettime(CLOCK_REALTIME, &tmout) == -1)
- {
- error("sema: clock_gettime failed - can't do timed wait");
- return -1;
- }
- tmout.tv_sec += (s->timeout / 1000);
- tmout.tv_nsec += (s->timeout % 1000) * 1000;
- timedOutFlag = sem_timedwait(s->handle, &tmout);
- /* roughly speaking the return value indicates timeouts. It also indicated
- * signals. We are glossing over this for the moment since it isn't really
- * interesting in this application
- * */
- #endif
- return timedOutFlag;
- }
- void sema_release(sbs_semaphore *s)
- {
- if (s->handle)
- {
- /* release the semaphore */
- #ifdef WIN32
- ReleaseSemaphore(s->handle, 1, NULL);
- #else
- sem_post(s->handle);
- #endif
-
- /* clean up */
- #ifdef WIN32
- CloseHandle(s->handle);
- #else
- sem_close(s->handle);
- #endif
- s->handle = NULL; /* prevent double release */
- } else {
- error("sema: attempt to release an semaphore that wasn't 'held'");
- }
- }
|