aboutsummaryrefslogtreecommitdiffstats
path: root/src/libstrongswan
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2012-08-20 16:58:15 +0200
committerMartin Willi <martin@revosec.ch>2012-08-20 17:20:26 +0200
commit907d3d0f1d4bde9738c7ba3a4b369de310efc830 (patch)
treed8e58e314a3e381d629445ed77f08563079a9e29 /src/libstrongswan
parentf39b3915cddd0cb668773fd20f62cae0fea7288c (diff)
downloadstrongswan-907d3d0f1d4bde9738c7ba3a4b369de310efc830.tar.bz2
strongswan-907d3d0f1d4bde9738c7ba3a4b369de310efc830.tar.xz
Add a mutex/condvar based semaphore implementation if sem_timedwait is unavailable
Fixes #214.
Diffstat (limited to 'src/libstrongswan')
-rw-r--r--src/libstrongswan/threading/semaphore.c69
1 files changed, 67 insertions, 2 deletions
diff --git a/src/libstrongswan/threading/semaphore.c b/src/libstrongswan/threading/semaphore.c
index b7ab9ce7a..c35cf1ea5 100644
--- a/src/libstrongswan/threading/semaphore.c
+++ b/src/libstrongswan/threading/semaphore.c
@@ -13,10 +13,14 @@
* for more details.
*/
-#include <semaphore.h>
-
#include <library.h>
+#ifdef HAVE_SEM_TIMEDWAIT
+#include <semaphore.h>
+#else /* !HAVE_SEM_TIMEDWAIT */
+#include <threading/condvar.h>
+#endif /* HAVE_SEM_TIMEDWAIT */
+
#include "semaphore.h"
typedef struct private_semaphore_t private_semaphore_t;
@@ -30,21 +34,50 @@ struct private_semaphore_t {
*/
semaphore_t public;
+#ifdef HAVE_SEM_TIMEDWAIT
/**
* wrapped POSIX semaphore object
*/
sem_t sem;
+#else /* !HAVE_SEM_TIMEDWAIT */
+
+ /**
+ * Mutex to lock count variable
+ */
+ mutex_t *mutex;
+
+ /**
+ * Condvar to signal count increase
+ */
+ condvar_t *cond;
+
+ /**
+ * Semaphore count value
+ */
+ u_int count;
+#endif /* HAVE_SEM_TIMEDWAIT */
};
METHOD(semaphore_t, wait_, void,
private_semaphore_t *this)
{
+#ifdef HAVE_SEM_TIMEDWAIT
sem_wait(&this->sem);
+#else /* !HAVE_SEM_TIMEDWAIT */
+ this->mutex->lock(this->mutex);
+ while (this->count == 0)
+ {
+ this->cond->wait(this->cond, this->mutex);
+ }
+ this->count--;
+ this->mutex->unlock(this->mutex);
+#endif /* HAVE_SEM_TIMEDWAIT */
}
METHOD(semaphore_t, timed_wait_abs, bool,
private_semaphore_t *this, timeval_t tv)
{
+#ifdef HAVE_SEM_TIMEDWAIT
timespec_t ts;
ts.tv_sec = tv.tv_sec;
@@ -53,6 +86,20 @@ METHOD(semaphore_t, timed_wait_abs, bool,
/* there are errors other than ETIMEDOUT possible, but we consider them
* all as timeout */
return sem_timedwait(&this->sem, &ts) == -1;
+#else /* !HAVE_SEM_TIMEDWAIT */
+ this->mutex->lock(this->mutex);
+ while (this->count == 0)
+ {
+ if (this->cond->timed_wait_abs(this->cond, this->mutex, tv))
+ {
+ this->mutex->unlock(this->mutex);
+ return TRUE;
+ }
+ }
+ this->count--;
+ this->mutex->unlock(this->mutex);
+ return FALSE;
+#endif /* HAVE_SEM_TIMEDWAIT */
}
METHOD(semaphore_t, timed_wait, bool,
@@ -72,13 +119,25 @@ METHOD(semaphore_t, timed_wait, bool,
METHOD(semaphore_t, post, void,
private_semaphore_t *this)
{
+#ifdef HAVE_SEM_TIMEDWAIT
sem_post(&this->sem);
+#else /* !HAVE_SEM_TIMEDWAIT */
+ this->mutex->lock(this->mutex);
+ this->count++;
+ this->mutex->unlock(this->mutex);
+ this->cond->signal(this->cond);
+#endif /* HAVE_SEM_TIMEDWAIT */
}
METHOD(semaphore_t, destroy, void,
private_semaphore_t *this)
{
+#ifdef HAVE_SEM_TIMEDWAIT
sem_destroy(&this->sem);
+#else /* !HAVE_SEM_TIMEDWAIT */
+ this->cond->destroy(this->cond);
+ this->mutex->destroy(this->mutex);
+#endif /* HAVE_SEM_TIMEDWAIT */
free(this);
}
@@ -99,7 +158,13 @@ semaphore_t *semaphore_create(u_int value)
},
);
+#ifdef HAVE_SEM_TIMEDWAIT
sem_init(&this->sem, 0, value);
+#else /* !HAVE_SEM_TIMEDWAIT */
+ this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
+ this->cond = condvar_create(CONDVAR_TYPE_DEFAULT);
+ this->count = value;
+#endif /* HAVE_SEM_TIMEDWAIT */
return &this->public;
}