From c1f4e7f71929900010fdbee31a2f9ac84ca99800 Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Wed, 15 Aug 2012 13:19:38 +0200 Subject: [PATCH] FreeTDM: Add span start/stop callbacks to ftdm_io_interface. Callbacks are invoked from ftdm_span_start/_stop(). I/O is started before SIG and shut down in reverse order. This is needed for ftmod_misdn, to move the mISDN message handling into a separate thread (solving the mISDN socket vs. FreeTDM API issues). With these callbacks, the I/O thread can be started after the span I/O configuration has been (successfully) completed and stopped before destroying the span. NOTE: Both SIG and I/O callbacks are called with the span mutex locked, so threads created or destroyed synchronously in either of the custom start/stop functions, can not use ftdm_span_*() functions that lock the span mutex (e.g. ftdm_span_get_channel_count()). Signed-off-by: Stefan Knoblich --- libs/freetdm/src/ftdm_io.c | 15 ++++++++++++++- libs/freetdm/src/include/freetdm.h | 8 ++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index ef29a96b0e..6986804753 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -760,11 +760,16 @@ FT_DECLARE(ftdm_status_t) ftdm_span_stop(ftdm_span_t *span) goto done; } + /* Stop SIG */ status = span->stop(span); - if (FTDM_SUCCESS == status) { + if (status == FTDM_SUCCESS) { ftdm_clear_flag(span, FTDM_SPAN_STARTED); } + /* Stop I/O */ + if (span->fio && span->fio->span_stop) { + status = span->fio->span_stop(span); + } done: ftdm_mutex_unlock(span->mutex); @@ -5309,6 +5314,14 @@ FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span) goto done; } + /* Start I/O */ + if (span->fio && span->fio->span_start) { + status = span->fio->span_start(span); + if (status != FTDM_SUCCESS) + goto done; + } + + /* Start SIG */ status = ftdm_report_initial_channels_alarms(span); if (status != FTDM_SUCCESS) { goto done; diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 8f5fb4f1f3..1476ee0158 100755 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -807,6 +807,8 @@ struct ftdm_memory_handler { #define FIO_CONFIGURE_SPAN_SIGNALING_ARGS (ftdm_span_t *span, fio_signal_cb_t sig_cb, ftdm_conf_parameter_t *ftdm_parameters) #define FIO_SIG_UNLOAD_ARGS (void) #define FIO_API_ARGS (ftdm_stream_handle_t *stream, const char *data) +#define FIO_SPAN_START_ARGS (ftdm_span_t *span) +#define FIO_SPAN_STOP_ARGS (ftdm_span_t *span) /*! \brief FreeTDM I/O layer interface function typedefs * You don't need these unless your implementing an I/O interface module (most users don't) */ @@ -853,6 +855,8 @@ typedef ftdm_status_t (*fio_configure_span_signaling_t) FIO_CONFIGURE_SPAN_SIGNA typedef ftdm_status_t (*fio_io_unload_t) FIO_IO_UNLOAD_ARGS ; typedef ftdm_status_t (*fio_sig_unload_t) FIO_SIG_UNLOAD_ARGS ; typedef ftdm_status_t (*fio_api_t) FIO_API_ARGS ; +typedef ftdm_status_t (*fio_span_start_t) FIO_SPAN_START_ARGS ; +typedef ftdm_status_t (*fio_span_stop_t) FIO_SPAN_STOP_ARGS ; /*! \brief FreeTDM I/O layer interface function prototype wrapper macros @@ -887,6 +891,8 @@ typedef ftdm_status_t (*fio_api_t) FIO_API_ARGS ; #define FIO_IO_UNLOAD_FUNCTION(name) ftdm_status_t name FIO_IO_UNLOAD_ARGS #define FIO_SIG_UNLOAD_FUNCTION(name) ftdm_status_t name FIO_SIG_UNLOAD_ARGS #define FIO_API_FUNCTION(name) ftdm_status_t name FIO_API_ARGS +#define FIO_SPAN_START_FUNCTION(name) ftdm_status_t name FIO_SPAN_START_ARGS +#define FIO_SPAN_STOP_FUNCTION(name) ftdm_status_t name FIO_SPAN_STOP_ARGS /*! \brief FreeTDM I/O layer function prototype wrapper macros * You don't need these unless your implementing an I/O interface module (most users don't) */ @@ -907,6 +913,8 @@ struct ftdm_io_interface { fio_span_next_event_t next_event; /*!< Retrieve an event from the span */ fio_channel_next_event_t channel_next_event; /*!< Retrieve an event from channel */ fio_api_t api; /*!< Execute a text command */ + fio_span_start_t span_start; /*!< Start span I/O */ + fio_span_stop_t span_stop; /*!< Stop span I/O */ }; /*! \brief FreeTDM supported I/O codecs */