*/
static void *zap_sangoma_boost_run(zap_thread_t *me, void *obj)
{
- zap_span_t *span = (zap_span_t *) obj;
+ zap_span_t *span = (zap_span_t *) obj;
sangomabc_connection_t *mcon, *pcon;
uint32_t ms = 10;
- zap_sangoma_boost_data_t *sangoma_boost_data = span->signal_data;
+ zap_sangoma_boost_data_t *sangoma_boost_data = span->signal_data;
mcon = &sangoma_boost_data->mcon;
pcon = &sangoma_boost_data->pcon;
break;
}
- if ((activity = zap_boost_wait_event(span, ms)) < 0) {
+ if ((activity = zap_boost_wait_event(span, -1)) < 0) {
zap_log(ZAP_LOG_ERROR, "zap_boost_wait_event failed\n");
goto error;
}
static zap_status_t zap_sangoma_boost_stop(zap_span_t *span)
{
+ int cnt = 10;
zap_status_t status = ZAP_SUCCESS;
zap_sangoma_boost_data_t *sangoma_boost_data = span->signal_data;
if (sangoma_boost_data->sigmod) {
+
/* FIXME: we should make sure the span thread is stopped (use pthread_kill or openzap thread kill function) */
/* 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_enqueue(sangoma_boost_data->boost_queue, NULL);
+ while(zap_test_flag(sangoma_boost_data, ZAP_SANGOMA_BOOST_RUNNING) && cnt-- > 0) {
+ zap_log(ZAP_LOG_DEBUG, "Waiting for boost thread\n");
+ zap_sleep(500);
+ }
zap_queue_destroy(&sangoma_boost_data->boost_queue);
return status;
}
wanpipe_tdm_api_t tdm_api;
memset(&tdm_api, 0, sizeof(tdm_api));
#ifdef LIBSANGOMA_VERSION
- sangstatus = sangoma_wait_obj_create(&sangoma_wait_obj, sockfd, SANGOMA_DEVICE_WAIT_OBJ);
+ /* we need SANGOMA_DEVICE_WAIT_OBJ_SIG and not SANGOMA_DEVICE_WAIT_OBJ alone because we need to call
+ * sangoma_wait_obj_sig to wake up any I/O waiters when closing the channel (typically on zap shutdown)
+ * this adds an extra pair of file descriptors to the waitable object
+ * */
+ sangstatus = sangoma_wait_obj_create(&sangoma_wait_obj, sockfd, SANGOMA_DEVICE_WAIT_OBJ_SIG);
if (sangstatus != SANG_STATUS_SUCCESS) {
zap_log(ZAP_LOG_ERROR, "failure create waitable object for s%dc%d\n", spanno, x);
continue;
*/
static ZIO_CLOSE_FUNCTION(wanpipe_close)
{
+#ifdef LIBSANGOMA_VERSION
+ sangoma_wait_obj_t *waitobj = zchan->mod_data;
+ /* kick any I/O waiters */
+ sangoma_wait_obj_signal(waitobj);
+#endif
return ZAP_SUCCESS;
}
{
#ifdef LIBSANGOMA_VERSION
if (zchan->mod_data) {
- sangoma_wait_obj_t *sangoma_wait_obj;
+ sangoma_wait_obj_t *sangoma_wait_obj;
sangoma_wait_obj = zchan->mod_data;
zchan->mod_data = NULL;
sangoma_wait_obj_delete(&sangoma_wait_obj);
return hash;
}
-
-static zap_status_t zap_span_destroy(zap_span_t *span)
-{
- zap_status_t status = ZAP_FAIL;
-
- if (zap_test_flag(span, ZAP_SPAN_CONFIGURED)) {
- if (span->stop) {
- span->stop(span);
- }
- if (span->zio && span->zio->span_destroy) {
- zap_log(ZAP_LOG_INFO, "Destroying span %u type (%s)\n", span->span_id, span->type);
- status = span->zio->span_destroy(span);
- zap_safe_free(span->type);
- zap_safe_free(span->dtmf_hangup);
- }
- }
-
- return status;
-}
-
static zap_status_t zap_channel_destroy(zap_channel_t *zchan)
{
return ZAP_SUCCESS;
}
+static zap_status_t zap_span_destroy(zap_span_t *span)
+{
+ zap_status_t status = ZAP_SUCCESS;
+ unsigned j;
+
+ zap_mutex_lock(span->mutex);
+
+ /* stop the signaling */
+ if (span->stop) {
+ status = span->stop(span);
+ }
+
+ /* destroy the channels */
+ zap_clear_flag(span, ZAP_SPAN_CONFIGURED);
+ for(j = 1; j <= span->chan_count && span->channels[j]; j++) {
+ zap_channel_t *cur_chan = span->channels[j];
+ if (cur_chan) {
+ if (zap_test_flag(cur_chan, ZAP_CHANNEL_CONFIGURED)) {
+ zap_channel_destroy(cur_chan);
+ }
+ zap_safe_free(cur_chan);
+ cur_chan = NULL;
+ }
+ }
+
+ /* destroy the I/O for the span */
+ if (span->zio && span->zio->span_destroy) {
+ zap_log(ZAP_LOG_INFO, "Destroying span %u type (%s)\n", span->span_id, span->type);
+ if (span->zio->span_destroy(span) != ZAP_SUCCESS) {
+ status = ZAP_FAIL;
+ }
+ zap_safe_free(span->type);
+ zap_safe_free(span->dtmf_hangup);
+ }
+
+ /* destroy final basic resources of the span data structure */
+ zap_mutex_unlock(span->mutex);
+ zap_mutex_destroy(&span->mutex);
+ zap_safe_free(span->signal_data);
+
+ return status;
+}
OZ_DECLARE(zap_status_t) zap_channel_get_alarms(zap_channel_t *zchan)
{
for (span = globals.spans; span; span = span->next) {
if (zap_test_flag(span, ZAP_SPAN_CONFIGURED)) {
for(j = 1; j <= span->chan_count && span->channels[j]; j++) {
- zap_channel_destroy(span->channels[j]);
+ zap_channel_t *toclose = span->channels[j];
+ if (zap_test_flag(toclose, ZAP_CHANNEL_INUSE)) {
+ zap_channel_close(&toclose);
+ }
i++;
}
}
return ZAP_FAIL;
}
+ if (!zap_test_flag(check, ZAP_CHANNEL_INUSE)) {
+ zap_log(ZAP_LOG_WARNING, "Called zap_channel_close but never zap_channel_open in chan %d:%d??\n", check->span_id, check->chan_id);
+ return ZAP_FAIL;
+ }
+
if (zap_test_flag(check, ZAP_CHANNEL_CONFIGURED)) {
zap_mutex_lock(check->mutex);
if (zap_test_flag(check, ZAP_CHANNEL_OPEN)) {
status = check->zio->close(check);
if (status == ZAP_SUCCESS) {
+ zap_clear_flag(check, ZAP_CHANNEL_INUSE);
zap_channel_reset(check);
*zchan = NULL;
}
OZ_DECLARE(zap_status_t) zap_global_destroy(void)
{
- unsigned int j;
zap_span_t *sp;
time_end();
if (cur_span) {
if (zap_test_flag(cur_span, ZAP_SPAN_CONFIGURED)) {
- zap_mutex_lock(cur_span->mutex);
- zap_clear_flag(cur_span, ZAP_SPAN_CONFIGURED);
- for(j = 1; j <= cur_span->chan_count && cur_span->channels[j]; j++) {
- zap_channel_t *cur_chan = cur_span->channels[j];
- if (cur_chan) {
- if (zap_test_flag(cur_chan, ZAP_CHANNEL_CONFIGURED)) {
- zap_channel_destroy(cur_chan);
- }
- zap_safe_free(cur_chan);
- cur_chan = NULL;
- }
- }
- zap_mutex_unlock(cur_span->mutex);
-
- if (cur_span->mutex) {
- zap_mutex_destroy(&cur_span->mutex);
- }
-
- zap_safe_free(cur_span->signal_data);
zap_span_destroy(cur_span);
}