freetdm: - Update ftmod_sangoma_isdn to use core state advance

- Added locking documentation (docs/locking.txt)
	 - Updated core state advance to use state processor in span
           rather than pushing the processor in the function arguments
This commit is contained in:
Moises Silva
2010-12-31 09:42:15 -05:00
parent 903d136481
commit 39d58e0452
7 changed files with 189 additions and 44 deletions

View File

@@ -356,7 +356,6 @@ typedef enum {
"PROGRESS_MEDIA", "ALARM_TRAP", "ALARM_CLEAR", \
"COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "COLLISION", "FACILITY", \
"TRACE", "TRACE_RAW", "INDICATION_COMPLETED", "INVALID"
/*! \brief Move from string to ftdm_signal_event_t and viceversa */
FTDM_STR2ENUM_P(ftdm_str2ftdm_signal_event, ftdm_signal_event2str, ftdm_signal_event_t)
@@ -653,7 +652,20 @@ typedef ftdm_status_t (*fio_span_get_sig_status_t) FIO_SPAN_GET_SIG_STATUS_ARGS;
typedef ftdm_status_t (*fio_span_poll_event_t) FIO_SPAN_POLL_EVENT_ARGS ;
typedef ftdm_status_t (*fio_span_next_event_t) FIO_SPAN_NEXT_EVENT_ARGS ;
typedef ftdm_status_t (*fio_channel_next_event_t) FIO_CHANNEL_NEXT_EVENT_ARGS ;
/*! \brief Callback for signal delivery (FTDM_SIGEVENT_START and friends)
* \note This callback is provided by the user during ftdm_configure_span_signaling
*
* \note You must NOT do any blocking during this callback since this function is
* most likely called in an internal signaling thread that can potentially be
* shared for all the channels in a span and blocking will delay processing
* (sometimes even audio processing) for other channels
*
* \note Although some simple FreeTDM APIs can work (ie: ftdm_span_get_id etc), the
* use of any FreeTDM call API (ie ftdm_channel_call_answer) is discouraged
*/
typedef ftdm_status_t (*fio_signal_cb_t) FIO_SIGNAL_CB_ARGS ;
typedef ftdm_status_t (*fio_event_cb_t) FIO_EVENT_CB_ARGS ;
typedef ftdm_status_t (*fio_configure_span_t) FIO_CONFIGURE_SPAN_ARGS ;
typedef ftdm_status_t (*fio_configure_t) FIO_CONFIGURE_ARGS ;

View File

@@ -500,15 +500,15 @@ struct ftdm_span {
ftdm_span_stop_t stop;
ftdm_channel_sig_read_t sig_read;
ftdm_channel_sig_write_t sig_write;
/* Private I/O data per span. Do not touch unless you are an I/O module */
void *io_data;
ftdm_channel_state_processor_t state_processor; /*!< This guy is called whenever state processing is required */
void *io_data; /*!< Private I/O data per span. Do not touch unless you are an I/O module */
char *type;
char *dtmf_hangup;
size_t dtmf_hangup_len;
ftdm_state_map_t *state_map;
ftdm_caller_data_t default_caller_data;
ftdm_queue_t *pendingchans;
ftdm_queue_t *pendingsignals;
ftdm_queue_t *pendingchans; /*!< Channels pending of state processing */
ftdm_queue_t *pendingsignals; /*!< Signals pending from being delivered to the user */
struct ftdm_span *next;
};

View File

@@ -86,15 +86,21 @@ typedef struct {
const char *file;
const char *func;
int line;
ftdm_channel_state_t state;
ftdm_channel_state_t last_state;
ftdm_time_t time;
ftdm_time_t end_time;
ftdm_channel_state_t state; /*!< Current state (processed or not) */
ftdm_channel_state_t last_state; /*!< Previous state */
ftdm_time_t time; /*!< Time the state was set */
ftdm_time_t end_time; /*!< Time the state processing was completed */
} ftdm_state_history_entry_t;
typedef ftdm_status_t (*ftdm_channel_state_processor_t)(ftdm_channel_t *fchan);
FT_DECLARE(ftdm_status_t) ftdm_channel_advance_states(ftdm_channel_t *fchan, ftdm_channel_state_processor_t processor);
/*!
* \brief Process channel states by invoking the channel state processing routine
* it will keep calling the processing routine while the state status
* is FTDM_STATE_STATUS_NEW, it will not do anything otherwise
*/
FT_DECLARE(ftdm_status_t) ftdm_channel_advance_states(ftdm_channel_t *fchan);
FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const char *function, int line, ftdm_channel_t *fchan);
#define ftdm_channel_complete_state(obj) _ftdm_channel_complete_state(__FILE__, __FUNCTION__, __LINE__, obj)
FT_DECLARE(int) ftdm_check_state_all(ftdm_span_t *span, ftdm_channel_state_t state);
@@ -171,16 +177,26 @@ struct ftdm_state_map {
};
typedef struct ftdm_state_map ftdm_state_map_t;
/*!\brief Set the state for a channel (the channel must be locked when calling this function)
* \note Signaling modules should use ftdm_set_state macro instead
* \note If this function is called with the wait parameter set to a non-zero value, the recursivity
* of the channel lock must be == 1 because the channel will be unlocked/locked when waiting */
FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(const char *file, const char *func, int line,
ftdm_channel_t *ftdmchan, ftdm_channel_state_t state, int wait);
/*!\brief Set the state of a channel immediately and implicitly complete the previous state */
/*!\brief Set the state of a channel immediately and implicitly complete the previous state if needed
* \note FTDM_SIGEVENT_INDICATION_COMPLETED will be sent if the state change
* is associated to some indication (ie FTDM_CHANNEL_INDICATE_PROCEED)
* \note The channel must be locked when calling this function
* */
FT_DECLARE(ftdm_status_t) _ftdm_set_state(const char *file, const char *func, int line,
ftdm_channel_t *fchan, ftdm_channel_state_t state);
#define ftdm_set_state(obj, s) _ftdm_set_state(__FILE__, __FUNCTION__, __LINE__, obj, s); \
/*!\brief This macro is deprecated, signaling modules should always lock the channel themselves anyways since they must
* process first the user pending state changes then set a new state before releasing the lock
* this macro is here for backwards compatibility, DO NOT USE IT in new code since it is *always* wrong to set
* a state in a signaling module without checking and processing the current state first (and for that you must lock the channel)
*/
#define ftdm_set_state_locked(obj, s) \
do { \