]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
finished zap queue and zap conditions implementation for Linux
authorMoises Silva <moy@sangoma.com>
Sat, 14 Nov 2009 02:04:38 +0000 (02:04 +0000)
committerMoises Silva <moy@sangoma.com>
Sat, 14 Nov 2009 02:04:38 +0000 (02:04 +0000)
git-svn-id: http://svn.openzap.org/svn/openzap/branches/sangoma_boost@860 a93c3328-9c30-0410-af19-c9cd2b2d52af

libs/freetdm/src/include/openzap.h
libs/freetdm/src/include/zap_threadmutex.h
libs/freetdm/src/include/zap_types.h
libs/freetdm/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c
libs/freetdm/src/ozmod/ozmod_sangoma_boost/sangoma_boost_client.h
libs/freetdm/src/ozmod/ozmod_sangoma_boost/zap_sangoma_boost.h
libs/freetdm/src/zap_io.c
libs/freetdm/src/zap_queue.c
libs/freetdm/src/zap_threadmutex.c

index 8c982403955a8950caca87c6fe97d067b870c034..8f135e173cee43539b6ae1e152405fa5155534ed 100644 (file)
@@ -579,6 +579,13 @@ struct zap_span {
 
 OZ_DECLARE_DATA extern zap_logger_t zap_log;
 
+typedef enum {
+       ZAP_CRASH_NEVER = 0,
+       ZAP_CRASH_ON_ASSERT
+} zap_crash_policy_t;
+
+OZ_DECLARE_DATA extern zap_crash_policy_t g_zap_crash_policy;
+
 struct zap_io_interface {
        const char *name;
        zio_configure_span_t configure_span;
@@ -597,22 +604,23 @@ struct zap_io_interface {
        zio_api_t api;
 };
 
-typedef void* zap_queue_t;
+struct zap_queue;
+#define zap_queue_t struct zap_queue
 
 /*! brief create a new queue */
-OZ_DECLARE(zap_queue_t) zap_queue_create(void);
+OZ_DECLARE(zap_status_t) zap_queue_create(zap_queue_t **queue, zap_size_t size);
 
 /*! Enqueue an object */
-OZ_DECLARE(zap_status_t) zap_queue_enqueue(zap_queue_t queue, void *obj);
+OZ_DECLARE(zap_status_t) zap_queue_enqueue(zap_queue_t *queue, void *obj);
 
 /*! dequeue an object from the queue */
-OZ_DECLARE(void *) zap_queue_dequeue(zap_queue_t queue);
+OZ_DECLARE(void *) zap_queue_dequeue(zap_queue_t *queue);
 
 /*! wait ms milliseconds for a queue to have available objects, -1 to wait forever */
-OZ_DECLARE(zap_status_t) zap_queue_wait(zap_queue_t queue, int ms);
+OZ_DECLARE(zap_status_t) zap_queue_wait(zap_queue_t *queue, int ms);
 
 /*! destroy the queue */ 
-OZ_DECLARE(void) zap_queue_destroy(zap_queue_t queue);
+OZ_DECLARE(zap_status_t) zap_queue_destroy(zap_queue_t **queue);
 
 OZ_DECLARE(zap_size_t) zap_fsk_modulator_generate_bit(zap_fsk_modulator_t *fsk_trans, int8_t bit, int16_t *buf, zap_size_t buflen);
 OZ_DECLARE(int32_t) zap_fsk_modulator_generate_carrier_bits(zap_fsk_modulator_t *fsk_trans, uint32_t bits);
@@ -683,6 +691,7 @@ OZ_DECLARE(const char *) zap_channel_get_var(zap_channel_t *zchan, const char *v
 OZ_DECLARE(zap_status_t) zap_channel_clear_vars(zap_channel_t *zchan);
 OZ_DECLARE(zap_status_t) zap_global_init(void);
 OZ_DECLARE(zap_status_t) zap_global_destroy(void);
+OZ_DECLARE(void) zap_global_set_crash_policy(zap_crash_policy_t policy);
 OZ_DECLARE(void) zap_global_set_logger(zap_logger_t logger);
 OZ_DECLARE(void) zap_global_set_default_logger(int level);
 OZ_DECLARE(uint32_t) zap_separate_string(char *buf, char delim, char **array, int arraylen);
@@ -722,6 +731,15 @@ ZIO_CODEC_FUNCTION(zio_alaw2ulaw);
 #define zap_mutex_unlock(_x) _zap_mutex_unlock(_x)
 #endif
 
+#define zap_assert(assertion, retval, msg) \
+       if (!(assertion)) { \
+               zap_log(ZAP_LOG_CRIT, msg); \
+               if (g_zap_crash_policy & ZAP_CRASH_ON_ASSERT) { \
+                       abort();  \
+               } else { \
+                       return retval; \
+               } \
+       }
 
 static __inline__ void zap_set_state_all(zap_span_t *span, zap_channel_state_t state)
 {
index 6e2af571ac02728cacc759010165ce2952022f1d..f131c48cf0fcb3de076601b276eb48e8625d584d 100644 (file)
  * constitutes an essential part of this license. No use of any covered code is authorized hereunder
  * except under this disclaimer. 
  *
+ * Contributors: 
+ *
+ * Moises Silva <moy@sangoma.com>
+ *
  */
 
 
@@ -25,6 +29,7 @@
 
 typedef struct zap_mutex zap_mutex_t;
 typedef struct zap_thread zap_thread_t;
+typedef struct zap_condition zap_condition_t;
 typedef void *(*zap_thread_function_t) (zap_thread_t *, void *);
 
 OZ_DECLARE(zap_status_t) zap_thread_create_detached(zap_thread_function_t func, void *data);
@@ -35,6 +40,10 @@ OZ_DECLARE(zap_status_t) zap_mutex_destroy(zap_mutex_t **mutex);
 OZ_DECLARE(zap_status_t) _zap_mutex_lock(zap_mutex_t *mutex);
 OZ_DECLARE(zap_status_t) _zap_mutex_trylock(zap_mutex_t *mutex);
 OZ_DECLARE(zap_status_t) _zap_mutex_unlock(zap_mutex_t *mutex);
+OZ_DECLARE(zap_status_t) zap_condition_create(zap_condition_t **cond, zap_mutex_t *mutex);
+OZ_DECLARE(zap_status_t) zap_condition_destroy(zap_condition_t **cond);
+OZ_DECLARE(zap_status_t) zap_condition_signal(zap_condition_t *cond);
+OZ_DECLARE(zap_status_t) zap_condition_wait(zap_condition_t *cond, int ms);
 
 #endif
 
index bff84883791a72e6882270482507cdec3650f774..e8fe8bd78ffc2dc72387fba65dd73691b5d74508 100644 (file)
@@ -619,7 +619,6 @@ typedef enum {
        ZAP_CAUSE_MEDIA_TIMEOUT = 604
 } zap_call_cause_t;
 
-
 #endif
 
 /* For Emacs:
index 688397d870f967dfbd14a961b7fb62822d26f72f..c1f7f74588067c30ea5bb968edbd623404919cc2 100644 (file)
@@ -45,6 +45,8 @@ zap_hash_t *g_boost_modules_hash = NULL;
 #define MAX_TRUNK_GROUPS 64
 static time_t congestion_timeouts[MAX_TRUNK_GROUPS];
 
+#define BOOST_QUEUE_SIZE 500
+
 /**
  * \brief Strange flag
  */
@@ -1221,12 +1223,15 @@ static void *zap_sangoma_boost_run(zap_thread_t *me, void *obj)
        mcon = &sangoma_boost_data->mcon;
        pcon = &sangoma_boost_data->pcon;       
 
+       /* sigmod overrides socket functionality if not null */
        if (sangoma_boost_data->sigmod) {
-               /* sigmod overrides socket functionality if not null */
-               mcon->sigmod = sangoma_boost_data->sigmod;
-               pcon->sigmod = sangoma_boost_data->sigmod;
                mcon->span = span;
                pcon->span = span;
+               /* everything could be retrieved through span, but let's use shortcuts */
+               mcon->sigmod = sangoma_boost_data->sigmod;
+               pcon->sigmod = sangoma_boost_data->sigmod;
+               mcon->boost_queue = sangoma_boost_data->boost_queue;
+               pcon->boost_queue = sangoma_boost_data->boost_queue;
        }
 
        if (zap_boost_connection_open(span) != ZAP_SUCCESS) {
@@ -1381,7 +1386,7 @@ static zap_status_t zap_sangoma_boost_stop(zap_span_t *span)
                /* I think stopping the span before destroying the queue makes sense
                   otherwise may be boost events would still arrive when the queue is already destroyed! */
                status = sangoma_boost_data->sigmod->stop_span(span);
-               zap_queue_destroy(sangoma_boost_data->boost_queue);
+               zap_queue_destroy(&sangoma_boost_data->boost_queue);
                return status;
        }
        return ZAP_SUCCESS;
@@ -1489,7 +1494,7 @@ static zap_state_map_t boost_state_map = {
 static BOOST_WRITE_MSG_FUNCTION(zap_boost_write_msg)
 {
        zap_sangoma_boost_data_t *sangoma_boost_data = span->signal_data;
-       sangomabc_queue_element_t *element = malloc(sizeof(*element));
+       sangomabc_queue_element_t *element = calloc(1, sizeof(*element));
        if (!element) {
                return ZAP_FAIL;
        }
@@ -1583,11 +1588,10 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_sangoma_boost_configure_span)
                }
        }
 
-       sangoma_boost_data = malloc(sizeof(*sangoma_boost_data));
+       sangoma_boost_data = calloc(1, sizeof(*sangoma_boost_data));
        if (!sangoma_boost_data) {
                FAIL_CONFIG_RETURN(ZAP_FAIL);
        }
-       memset(sangoma_boost_data, 0, sizeof(*sangoma_boost_data));
 
        /* WARNING: be sure to release this mutex on errors inside this if() */
        zap_mutex_lock(g_boost_modules_mutex);
@@ -1618,8 +1622,7 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_sangoma_boost_configure_span)
 
        if (sigmod_iface) {
                /* try to create the boost queue */
-               sangoma_boost_data->boost_queue = zap_queue_create();
-               if (!sangoma_boost_data->boost_queue) {
+               if (zap_queue_create(&sangoma_boost_data->boost_queue, BOOST_QUEUE_SIZE) != ZAP_SUCCESS) {
                        zap_log(ZAP_LOG_ERROR, "Span %s could not create its boost queue!\n", span->name);
                        FAIL_CONFIG_RETURN(ZAP_FAIL);
                }
index a18d3e7eeb8ff10357ce58d0ad10714cad6f33b8..e38ea050b3ff7e99a552834300c70f231f0edd3a 100644 (file)
@@ -108,7 +108,7 @@ struct sangomabc_connection {
        uint32_t hb_elapsed;
        /* boost signaling mod interface pointer (if not working in TCP mode) */
        boost_sigmod_interface_t *sigmod;
-       zap_queue_t boost_queue;        
+       zap_queue_t *boost_queue;       
        zap_span_t *span;
 };
 
index fc2fc953fdfac942836311264a1fe446f46502ed..e08d98b5985cb78a95325f802ae8ef26a41d30f8 100644 (file)
@@ -50,7 +50,7 @@ typedef struct zap_sangoma_boost_data {
        zio_signal_cb_t signal_cb;
        uint32_t flags;
        boost_sigmod_interface_t *sigmod;
-       zap_queue_t boost_queue;
+       zap_queue_t *boost_queue;
 } zap_sangoma_boost_data_t;
 
 #endif
index 1ae1796057b3ba2a39c958b38c7a90a36954df1e..48ea8e0f05f4b973facb055248069261dc09c8f5 100644 (file)
@@ -176,8 +176,15 @@ static void default_logger(const char *file, const char *func, int line, int lev
 
 }
 
+OZ_DECLARE_DATA zap_crash_policy_t g_zap_crash_policy = ZAP_CRASH_NEVER;
+
 OZ_DECLARE_DATA zap_logger_t zap_log = null_logger;
 
+OZ_DECLARE(void) zap_global_set_crash_policy(zap_crash_policy_t policy)
+{
+       g_zap_crash_policy = policy;
+}
+
 OZ_DECLARE(void) zap_global_set_logger(zap_logger_t logger)
 {
        if (logger) {
index 24f3dcaf51e3d21d0b46ca48fbe83fed6e3eef48..93fcd76f1176b5ea1537ae337ec0f62b2259e75a 100644 (file)
 
 #include "openzap.h"
 
-OZ_DECLARE(zap_queue_t) zap_queue_create(void)
+#undef zap_queue_t
+#define ZAP_QUEUE_SIZE
+typedef struct zap_queue {
+       zap_mutex_t *mutex;
+       zap_condition_t *condition;
+       zap_size_t size;
+       unsigned rindex;
+       unsigned windex;
+       void **elements;
+} zap_queue_t;
+
+OZ_DECLARE(zap_status_t) zap_queue_create(zap_queue_t **outqueue, zap_size_t size)
 {
-       return NULL;
+       zap_assert(outqueue, ZAP_FAIL, "Queue double pointer is null\n");
+       zap_assert(size > 0, ZAP_FAIL, "Queue size is not bigger than 0\n");
+
+       *outqueue = NULL;
+       zap_queue_t *queue = calloc(1, sizeof(*queue));
+       if (!queue) {
+               return ZAP_FAIL;
+       }
+
+       queue->elements = calloc(1, (sizeof(void*)*size));
+       if (!queue->elements) {
+               goto failed;
+       }
+       queue->size = size;
+
+       if (zap_mutex_create(&queue->mutex) != ZAP_SUCCESS) {
+               goto failed;
+       }
+
+       if (zap_condition_create(&queue->condition, queue->mutex) != ZAP_SUCCESS) {
+               goto failed;
+       }
+
+       *outqueue = queue;      
+       return ZAP_SUCCESS;
+
+failed:
+       if (queue) {
+               if (queue->condition) {
+                       zap_condition_destroy(&queue->condition);
+               }
+               if (queue->mutex) {
+                       zap_mutex_destroy(&queue->mutex);
+               }
+               zap_safe_free(queue->elements);
+               zap_safe_free(queue);
+       }
+       return ZAP_FAIL;
 }
 
-OZ_DECLARE(zap_status_t) zap_queue_enqueue(zap_queue_t queue, void *obj)
+OZ_DECLARE(zap_status_t) zap_queue_enqueue(zap_queue_t *queue, void *obj)
 {
-       return ZAP_FAIL;
+       zap_status_t status = ZAP_FAIL;
+
+       zap_assert(queue != NULL, ZAP_FAIL, "Queue is null!");
+
+       zap_mutex_lock(queue->mutex);
+
+       if (queue->windex == queue->size) {
+               /* try to see if we can wrap around */
+               queue->windex = 0;
+       }
+
+       if (queue->windex == queue->rindex) {
+               zap_log(ZAP_LOG_ERROR, "Failed to enqueue obj %p in queue %p, no more room! windex == rindex == %d!\n", obj, queue, queue->windex);
+               goto done;
+       }
+       queue->elements[queue->windex++] = obj;
+       status = ZAP_SUCCESS;
+
+       /* wake up queue reader */
+       zap_condition_signal(queue->condition);
+
+done:
+
+       zap_mutex_unlock(queue->mutex);
+
+       return status;
 }
 
-OZ_DECLARE(void *) zap_queue_dequeue(zap_queue_t queue)
+OZ_DECLARE(void *) zap_queue_dequeue(zap_queue_t *queue)
 {
-       return NULL;
+       void *obj = NULL;
+
+       zap_assert(queue != NULL, NULL, "Queue is null!");
+
+       zap_mutex_lock(queue->mutex);
+
+       if (!queue->elements[queue->rindex]) {
+               goto done;
+       }
+
+       obj = queue->elements[queue->rindex];
+       queue->elements[queue->rindex] = NULL;
+       if (queue->rindex == queue->size) {
+               queue->rindex = 0;
+       }
+
+done:
+       zap_mutex_unlock(queue->mutex);
+       return obj;
 }
 
-OZ_DECLARE(zap_status_t) zap_queue_wait(zap_queue_t queue, int ms)
+OZ_DECLARE(zap_status_t) zap_queue_wait(zap_queue_t *queue, int ms)
 {
-       return ZAP_FAIL;
+       zap_assert(queue != NULL, ZAP_FAIL, "Queue is null!");
+       
+       zap_mutex_lock(queue->mutex);
+
+       if (queue->elements[queue->rindex]) {
+               zap_mutex_unlock(queue->mutex);
+               return ZAP_SUCCESS;
+       }
+
+       if (zap_condition_wait(queue->condition, ms)) {
+               zap_mutex_unlock(queue->mutex);
+               return ZAP_FAIL;
+       }
+
+       zap_mutex_unlock(queue->mutex);
+
+       return ZAP_SUCCESS;
 }
 
-OZ_DECLARE(void) zap_queue_destroy(zap_queue_t queue)
+OZ_DECLARE(zap_status_t) zap_queue_destroy(zap_queue_t **inqueue)
 {
+       zap_queue_t *queue = NULL;
+       zap_assert(inqueue != NULL, ZAP_FAIL, "Queue is null!");
+       zap_assert(*inqueue != NULL, ZAP_FAIL, "Queue is null!");
 
+       queue = *inqueue;
+       zap_condition_destroy(&queue->condition);
+       zap_mutex_destroy(&queue->mutex);
+       zap_safe_free(queue->elements);
+       zap_safe_free(queue);
+       *inqueue = NULL;
+       return ZAP_SUCCESS;
 }
+
 #endif
 
 /* For Emacs:
index b6bc8435b6ef9d61ed90eb3a1cc0288590780813..fa302e56a6db6398ec2d53395a1ec195bb51a4ed 100644 (file)
@@ -34,6 +34,10 @@ struct zap_mutex {
        CRITICAL_SECTION mutex;
 };
 
+struct zap_condition {
+       HANDLE condition;
+};
+
 #else
 
 #include <pthread.h>
@@ -44,6 +48,11 @@ struct zap_mutex {
        pthread_mutex_t mutex;
 };
 
+struct zap_condition {
+       pthread_cond_t condition;
+       pthread_mutex_t *mutex;
+};
+
 #endif
 
 struct zap_thread {
@@ -222,8 +231,91 @@ OZ_DECLARE(zap_status_t) _zap_mutex_unlock(zap_mutex_t *mutex)
 }
 
 
+OZ_DECLARE(zap_status_t) zap_condition_create(zap_condition_t **incondition, zap_mutex_t *mutex)
+{
+       zap_condition_t *condition = NULL;
+
+       zap_assert(condition != NULL, ZAP_FAIL, "Condition double pointer is null!\n");
+       zap_assert(mutex != NULL, ZAP_FAIL, "Mutex for condition must not be null!\n");
+
+#ifdef WIN32
+       return ZAP_NOTIMPL;
+#endif
+
+       condition = malloc(sizeof(*condition));
+       if (!condition) {
+               return ZAP_FAIL;
+       }
+
+#ifndef WIN32
+       condition->mutex = &mutex->mutex;
+
+       if (pthread_cond_init(&condition->condition, NULL)) {
+               goto failed;
+       }
+
+       return ZAP_SUCCESS;
+
+failed:
+       if (condition) {
+               zap_safe_free(condition);
+       }
+       return ZAP_FAIL;
+#endif
+}
+
+OZ_DECLARE(zap_status_t) zap_condition_wait(zap_condition_t *condition, int ms)
+{
+       zap_assert(condition != NULL, ZAP_FAIL, "Condition is null!\n");
+       int res = 0;
+#ifdef WIN32
+       return ZAP_NOTIMPL;
+#else
+       if (ms > 0) {
+               struct timespec waitms = { 0, ((ms * 1000) * 1000)};
+               res = pthread_cond_timedwait(&condition->condition, condition->mutex, &waitms);
+       } else {
+               res = pthread_cond_wait(&condition->condition, condition->mutex);
+       }
+       if (res != 0) {
+               if (res == ETIMEDOUT) {
+                       return ZAP_TIMEOUT;
+               }
+               return ZAP_FAIL;
+       }
+#endif
+       return ZAP_SUCCESS;
+}
 
+OZ_DECLARE(zap_status_t) zap_condition_signal(zap_condition_t *condition)
+{
+       zap_assert(condition != NULL, ZAP_FAIL, "Condition is null!\n");
+#ifdef WIN32
+       return ZAP_NOTIMPL;
+#else
+       if (pthread_cond_signal(&condition->condition)) {
+               return ZAP_FAIL;
+       }
+#endif
+       return ZAP_SUCCESS;
+}
 
+OZ_DECLARE(zap_status_t) zap_condition_destroy(zap_condition_t **incondition)
+{
+       zap_condition_t *condition = NULL;
+       zap_assert(incondition != NULL, ZAP_FAIL, "Condition null when destroying!\n");
+       condition = *incondition;
+#ifdef WIN32
+       return ZAP_NOTIMPL;
+#else
+       if (pthread_cond_destroy(&condition->condition)) {
+               return ZAP_FAIL;
+       }
+       zap_safe_free(condition);
+#endif
+       *incondition = NULL;
+       return ZAP_SUCCESS;
+}
 
 /* For Emacs:
  * Local Variables: