summaryrefslogtreecommitdiff
path: root/pjlib/src/pj/os_core_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'pjlib/src/pj/os_core_unix.c')
-rw-r--r--pjlib/src/pj/os_core_unix.c123
1 files changed, 102 insertions, 21 deletions
diff --git a/pjlib/src/pj/os_core_unix.c b/pjlib/src/pj/os_core_unix.c
index 7810eb2..ff8ba68 100644
--- a/pjlib/src/pj/os_core_unix.c
+++ b/pjlib/src/pj/os_core_unix.c
@@ -1,4 +1,4 @@
-/* $Id: os_core_unix.c 3999 2012-03-30 07:10:13Z bennylp $ */
+/* $Id: os_core_unix.c 4359 2013-02-21 11:18:36Z bennylp $ */
/*
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
@@ -97,7 +97,18 @@ struct pj_sem_t
#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0
struct pj_event_t
{
- char obj_name[PJ_MAX_OBJ_NAME];
+ enum event_state {
+ EV_STATE_OFF,
+ EV_STATE_SET,
+ EV_STATE_PULSED
+ } state;
+
+ pj_mutex_t mutex;
+ pthread_cond_t cond;
+
+ pj_bool_t auto_reset;
+ unsigned threads_waiting;
+ unsigned threads_to_release;
};
#endif /* PJ_HAS_EVENT_OBJ */
@@ -1700,13 +1711,48 @@ PJ_DEF(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,
pj_bool_t manual_reset, pj_bool_t initial,
pj_event_t **ptr_event)
{
- pj_assert(!"Not supported!");
- PJ_UNUSED_ARG(pool);
- PJ_UNUSED_ARG(name);
- PJ_UNUSED_ARG(manual_reset);
- PJ_UNUSED_ARG(initial);
- PJ_UNUSED_ARG(ptr_event);
- return PJ_EINVALIDOP;
+ pj_event_t *event;
+
+ event = PJ_POOL_ALLOC_T(pool, pj_event_t);
+
+ init_mutex(&event->mutex, name, PJ_MUTEX_SIMPLE);
+ pthread_cond_init(&event->cond, 0);
+ event->auto_reset = !manual_reset;
+ event->threads_waiting = 0;
+
+ if (initial) {
+ event->state = EV_STATE_SET;
+ event->threads_to_release = 1;
+ } else {
+ event->state = EV_STATE_OFF;
+ event->threads_to_release = 0;
+ }
+
+ *ptr_event = event;
+ return PJ_SUCCESS;
+}
+
+static void event_on_one_release(pj_event_t *event)
+{
+ if (event->state == EV_STATE_SET) {
+ if (event->auto_reset) {
+ event->threads_to_release = 0;
+ event->state = EV_STATE_OFF;
+ } else {
+ /* Manual reset remains on */
+ }
+ } else {
+ if (event->auto_reset) {
+ /* Only release one */
+ event->threads_to_release = 0;
+ event->state = EV_STATE_OFF;
+ } else {
+ event->threads_to_release--;
+ pj_assert(event->threads_to_release >= 0);
+ if (event->threads_to_release==0)
+ event->state = EV_STATE_OFF;
+ }
+ }
}
/*
@@ -1714,8 +1760,14 @@ PJ_DEF(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,
*/
PJ_DEF(pj_status_t) pj_event_wait(pj_event_t *event)
{
- PJ_UNUSED_ARG(event);
- return PJ_EINVALIDOP;
+ pthread_mutex_lock(&event->mutex.mutex);
+ event->threads_waiting++;
+ while (event->state == EV_STATE_OFF)
+ pthread_cond_wait(&event->cond, &event->mutex.mutex);
+ event->threads_waiting--;
+ event_on_one_release(event);
+ pthread_mutex_unlock(&event->mutex.mutex);
+ return PJ_SUCCESS;
}
/*
@@ -1723,8 +1775,16 @@ PJ_DEF(pj_status_t) pj_event_wait(pj_event_t *event)
*/
PJ_DEF(pj_status_t) pj_event_trywait(pj_event_t *event)
{
- PJ_UNUSED_ARG(event);
- return PJ_EINVALIDOP;
+ pj_status_t status;
+
+ pthread_mutex_lock(&event->mutex.mutex);
+ status = event->state != EV_STATE_OFF ? PJ_SUCCESS : -1;
+ if (status==PJ_SUCCESS) {
+ event_on_one_release(event);
+ }
+ pthread_mutex_unlock(&event->mutex.mutex);
+
+ return status;
}
/*
@@ -1732,8 +1792,15 @@ PJ_DEF(pj_status_t) pj_event_trywait(pj_event_t *event)
*/
PJ_DEF(pj_status_t) pj_event_set(pj_event_t *event)
{
- PJ_UNUSED_ARG(event);
- return PJ_EINVALIDOP;
+ pthread_mutex_lock(&event->mutex.mutex);
+ event->threads_to_release = 1;
+ event->state = EV_STATE_SET;
+ if (event->auto_reset)
+ pthread_cond_signal(&event->cond);
+ else
+ pthread_cond_broadcast(&event->cond);
+ pthread_mutex_unlock(&event->mutex.mutex);
+ return PJ_SUCCESS;
}
/*
@@ -1741,8 +1808,18 @@ PJ_DEF(pj_status_t) pj_event_set(pj_event_t *event)
*/
PJ_DEF(pj_status_t) pj_event_pulse(pj_event_t *event)
{
- PJ_UNUSED_ARG(event);
- return PJ_EINVALIDOP;
+ pthread_mutex_lock(&event->mutex.mutex);
+ if (event->threads_waiting) {
+ event->threads_to_release = event->auto_reset ? 1 :
+ event->threads_waiting;
+ event->state = EV_STATE_PULSED;
+ if (event->threads_to_release==1)
+ pthread_cond_signal(&event->cond);
+ else
+ pthread_cond_broadcast(&event->cond);
+ }
+ pthread_mutex_unlock(&event->mutex.mutex);
+ return PJ_SUCCESS;
}
/*
@@ -1750,8 +1827,11 @@ PJ_DEF(pj_status_t) pj_event_pulse(pj_event_t *event)
*/
PJ_DEF(pj_status_t) pj_event_reset(pj_event_t *event)
{
- PJ_UNUSED_ARG(event);
- return PJ_EINVALIDOP;
+ pthread_mutex_lock(&event->mutex.mutex);
+ event->state = EV_STATE_OFF;
+ event->threads_to_release = 0;
+ pthread_mutex_unlock(&event->mutex.mutex);
+ return PJ_SUCCESS;
}
/*
@@ -1759,8 +1839,9 @@ PJ_DEF(pj_status_t) pj_event_reset(pj_event_t *event)
*/
PJ_DEF(pj_status_t) pj_event_destroy(pj_event_t *event)
{
- PJ_UNUSED_ARG(event);
- return PJ_EINVALIDOP;
+ pj_mutex_destroy(&event->mutex);
+ pthread_cond_destroy(&event->cond);
+ return PJ_SUCCESS;
}
#endif /* PJ_HAS_EVENT_OBJ */