From de9803414537a12ce687607f02fe1f66f57a6b94 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Sun, 25 Dec 2011 20:49:10 -0500 Subject: [PATCH] freetdm: - Extend ftdm interrupt object to notify which IO events are ready in the device - Add definition of FTDM_MAX_SIG_PARAMETERS to have a standard limit for signaling module parameters --- libs/freetdm/mod_freetdm/mod_freetdm.c | 14 ++--- libs/freetdm/src/ftdm_io.c | 2 +- libs/freetdm/src/ftdm_queue.c | 2 +- libs/freetdm/src/ftdm_state.c | 2 +- libs/freetdm/src/ftdm_threadmutex.c | 57 +++++++++++++++++---- libs/freetdm/src/include/freetdm.h | 11 ++-- libs/freetdm/src/include/ftdm_declare.h | 8 +++ libs/freetdm/src/include/ftdm_threadmutex.h | 3 +- 8 files changed, 70 insertions(+), 29 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 3f461e8ab1..ff2c94f72d 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2828,7 +2828,7 @@ static void parse_gsm_spans(switch_xml_t cfg, switch_xml_t spans) ftdm_status_t zstatus = FTDM_FAIL; const char *context = "default"; const char *dialplan = "XML"; - ftdm_conf_parameter_t spanparameters[30]; + ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS]; char *id = (char *) switch_xml_attr(myspan, "id"); char *name = (char *) switch_xml_attr(myspan, "name"); char *configname = (char *) switch_xml_attr(myspan, "cfgprofile"); @@ -2917,7 +2917,7 @@ static void parse_bri_pri_spans(switch_xml_t cfg, switch_xml_t spans) ftdm_status_t zstatus = FTDM_FAIL; const char *context = "default"; const char *dialplan = "XML"; - ftdm_conf_parameter_t spanparameters[30]; + ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS]; char *id = (char *) switch_xml_attr(myspan, "id"); char *name = (char *) switch_xml_attr(myspan, "name"); char *configname = (char *) switch_xml_attr(myspan, "cfgprofile"); @@ -3096,7 +3096,7 @@ static switch_status_t load_config(void) ftdm_status_t zstatus = FTDM_FAIL; const char *context = "default"; const char *dialplan = "XML"; - ftdm_conf_parameter_t spanparameters[30]; + ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS]; char *id = (char *) switch_xml_attr(myspan, "id"); char *name = (char *) switch_xml_attr(myspan, "name"); char *configname = (char *) switch_xml_attr(myspan, "cfgprofile"); @@ -3498,7 +3498,7 @@ static switch_status_t load_config(void) if ((spans = switch_xml_child(cfg, "pri_spans"))) { for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) { char *name = (char *) switch_xml_attr(myspan, "name"); - ftdm_conf_parameter_t spanparameters[10]; + ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS]; ftdm_status_t zstatus = FTDM_FAIL; const char *context = "default"; const char *dialplan = "XML"; @@ -3566,7 +3566,7 @@ static switch_status_t load_config(void) ftdm_status_t zstatus = FTDM_FAIL; unsigned paramindex = 0; - ftdm_conf_parameter_t spanparameters[10]; + ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS]; const char *context = "default"; const char *dialplan = "XML"; ftdm_span_t *span = NULL; @@ -3624,7 +3624,7 @@ static switch_status_t load_config(void) if ((spans = switch_xml_child(cfg, "libpri_spans"))) { for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) { char *name = (char *) switch_xml_attr(myspan, "name"); - ftdm_conf_parameter_t spanparameters[10]; + ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS]; ftdm_status_t zstatus = FTDM_FAIL; const char *context = "default"; const char *dialplan = "XML"; @@ -3699,7 +3699,7 @@ static switch_status_t load_config(void) uint32_t span_id = 0; ftdm_span_t *span = NULL; - ftdm_conf_parameter_t spanparameters[30]; + ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS]; unsigned paramindex = 0; if (!name) { diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index f08eeaacf7..e00e0f3141 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -5633,7 +5633,7 @@ static void *ftdm_cpu_monitor_run(ftdm_thread_t *me, void *obj) static ftdm_status_t ftdm_cpu_monitor_start(void) { - if (ftdm_interrupt_create(&globals.cpu_monitor.interrupt, FTDM_INVALID_SOCKET) != FTDM_SUCCESS) { + if (ftdm_interrupt_create(&globals.cpu_monitor.interrupt, FTDM_INVALID_SOCKET, FTDM_NO_FLAGS) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "Failed to create CPU monitor interrupt\n"); return FTDM_FAIL; } diff --git a/libs/freetdm/src/ftdm_queue.c b/libs/freetdm/src/ftdm_queue.c index 75d18033da..625f22ec36 100644 --- a/libs/freetdm/src/ftdm_queue.c +++ b/libs/freetdm/src/ftdm_queue.c @@ -98,7 +98,7 @@ static ftdm_status_t ftdm_std_queue_create(ftdm_queue_t **outqueue, ftdm_size_t goto failed; } - if (ftdm_interrupt_create(&queue->interrupt, FTDM_INVALID_SOCKET) != FTDM_SUCCESS) { + if (ftdm_interrupt_create(&queue->interrupt, FTDM_INVALID_SOCKET, FTDM_NO_FLAGS) != FTDM_SUCCESS) { goto failed; } diff --git a/libs/freetdm/src/ftdm_state.c b/libs/freetdm/src/ftdm_state.c index d3f99f6074..e2ccf83747 100644 --- a/libs/freetdm/src/ftdm_state.c +++ b/libs/freetdm/src/ftdm_state.c @@ -254,7 +254,7 @@ static ftdm_status_t ftdm_core_set_state(const char *file, const char *func, int } if (!ftdmchan->state_completed_interrupt) { - status = ftdm_interrupt_create(&ftdmchan->state_completed_interrupt, FTDM_INVALID_SOCKET); + status = ftdm_interrupt_create(&ftdmchan->state_completed_interrupt, FTDM_INVALID_SOCKET, FTDM_NO_FLAGS); if (status != FTDM_SUCCESS) { ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_CRIT, "Failed to create state change interrupt when moving from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state)); diff --git a/libs/freetdm/src/ftdm_threadmutex.c b/libs/freetdm/src/ftdm_threadmutex.c index 56653811fa..a659adf11d 100644 --- a/libs/freetdm/src/ftdm_threadmutex.c +++ b/libs/freetdm/src/ftdm_threadmutex.c @@ -73,6 +73,8 @@ struct ftdm_mutex { struct ftdm_interrupt { ftdm_socket_t device; + ftdm_wait_flag_t device_input_flags; + ftdm_wait_flag_t device_output_flags; #ifdef WIN32 /* for generic interruption */ HANDLE event; @@ -323,7 +325,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_mutex_unlock(const char *file, int line, const c } -FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **ininterrupt, ftdm_socket_t device) +FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **ininterrupt, ftdm_socket_t device, ftdm_wait_flag_t device_flags) { ftdm_status_t status = FTDM_SUCCESS; ftdm_interrupt_t *interrupt = NULL; @@ -340,6 +342,7 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **ininterrupt, } interrupt->device = device; + interrupt->device_input_flags = device_flags; #ifdef WIN32 interrupt->event = CreateEvent(NULL, FALSE, FALSE, NULL); if (!interrupt->event) { @@ -389,15 +392,16 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_wait(ftdm_interrupt_t *interrupt, int m char pipebuf[255]; #endif - ftdm_assert_return(interrupt != NULL, FTDM_FAIL, "Condition is null!\n"); - + ftdm_assert_return(interrupt != NULL, FTDM_FAIL, "Interrupt is null!\n"); + interrupt->device_output_flags = FTDM_NO_FLAGS; /* start implementation */ #ifdef WIN32 ints[0] = interrupt->event; if (interrupt->device != FTDM_INVALID_SOCKET) { num++; ints[1] = interrupt->device; + ftdm_log(FTDM_LOG_CRIT, "implement me! (Windows support for device_output_flags member!)\n", size); } res = WaitForMultipleObjects(num, ints, FALSE, ms >= 0 ? ms : INFINITE); switch (res) { @@ -422,7 +426,7 @@ pollagain: if (interrupt->device != FTDM_INVALID_SOCKET) { num++; ints[1].fd = interrupt->device; - ints[1].events = POLLIN; + ints[1].events = interrupt->device_input_flags; ints[1].revents = 0; } @@ -446,7 +450,17 @@ pollagain: ftdm_log(FTDM_LOG_CRIT, "reading interrupt descriptor failed (%s)\n", strerror(errno)); } } - + if (interrupt->device != FTDM_INVALID_SOCKET) { + if (ints[1].revents & POLLIN) { + interrupt->device_output_flags |= FTDM_READ; + } + if (ints[1].revents & POLLOUT) { + interrupt->device_output_flags |= FTDM_WRITE; + } + if (ints[1].revents & POLLPRI) { + interrupt->device_output_flags |= FTDM_EVENTS; + } + } return FTDM_SUCCESS; #endif } @@ -515,10 +529,12 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interru for (i = 0; i < size; i++) { ints[i] = interrupts[i]->event; + interrupts[i]->device_output_flags = FTDM_NO_FLAGS; if (interrupts[i]->device != FTDM_INVALID_SOCKET) { - + /* WARNING: if the device is ready for data we must implement for Windows the device_output_flags member */ ints[size+numdevices] = interrupts[i]->device; numdevices++; + ftdm_log(FTDM_LOG_CRIT, "implement me! (Windows support for device_data_ready member!)\n", size); } } @@ -548,17 +564,16 @@ pollagain: ints[i].events = POLLIN; ints[i].revents = 0; ints[i].fd = interrupts[i]->readfd; + interrupts[i]->device_output_flags = FTDM_NO_FLAGS; if (interrupts[i]->device != FTDM_INVALID_SOCKET) { - ints[size+numdevices].events = POLLIN; + ints[size+numdevices].events = interrupts[i]->device_input_flags; ints[size+numdevices].revents = 0; ints[size+numdevices].fd = interrupts[i]->device; - numdevices++; } } res = poll(ints, size + numdevices, ms); - if (res == -1) { if (errno == EINTR) { goto pollagain; @@ -571,7 +586,8 @@ pollagain: return FTDM_TIMEOUT; } - /* check for events in the pipes, NOT in the devices */ + /* check for events in the pipes and in the devices, but service only the pipes */ + numdevices = 0; for (i = 0; i < size; i++) { if (ints[i].revents & POLLIN) { res = read(ints[i].fd, pipebuf, sizeof(pipebuf)); @@ -579,6 +595,18 @@ pollagain: ftdm_log(FTDM_LOG_CRIT, "reading interrupt descriptor failed (%s)\n", strerror(errno)); } } + if (interrupts[i]->device != FTDM_INVALID_SOCKET) { + if (ints[size+numdevices].revents & POLLIN) { + interrupts[i]->device_output_flags |= FTDM_READ; + } + if (ints[size+numdevices].revents & POLLOUT) { + interrupts[i]->device_output_flags |= FTDM_WRITE; + } + if (ints[size+numdevices].revents & POLLPRI) { + interrupts[i]->device_output_flags |= FTDM_EVENTS; + } + numdevices++; + } } #else /* for MacOS compilation, unused vars */ @@ -587,6 +615,15 @@ pollagain: return FTDM_SUCCESS; } +FT_DECLARE(ftdm_wait_flag_t) ftdm_interrupt_device_ready(ftdm_interrupt_t *interrupt) +{ +#if defined(__WINDOWS__) + /* device output flags are not currently filled for Windows upon returning from a wait function */ + ftdm_log(FTDM_LOG_CRIT, "IMPLEMENT ME!\n"); +#endif + return interrupt->device_output_flags; +} + /* For Emacs: * Local Variables: * mode:c diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 81f31e4ff8..32d883c9b4 100755 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -62,6 +62,9 @@ /*! \brief Max number of groups */ #define FTDM_MAX_GROUPS_INTERFACE FTDM_MAX_SPANS_INTERFACE +/*! \brief Max number of key=value pairs to be sent as signaling stack parameters */ +#define FTDM_MAX_SIG_PARAMETERS 30 + #define FTDM_INVALID_INT_PARM 0xFF /*! \brief Thread/Mutex OS abstraction API. */ @@ -621,14 +624,6 @@ typedef enum { FTDM_CRASH_ON_ASSERT } ftdm_crash_policy_t; -/*! \brief I/O waiting flags */ -typedef enum { - FTDM_NO_FLAGS = 0, - FTDM_READ = (1 << 0), - FTDM_WRITE = (1 << 1), - FTDM_EVENTS = (1 << 2) -} ftdm_wait_flag_t; - /*! \brief Signaling configuration parameter for the stacks (variable=value pair) */ typedef struct ftdm_conf_parameter { const char *var; diff --git a/libs/freetdm/src/include/ftdm_declare.h b/libs/freetdm/src/include/ftdm_declare.h index 9c7f9cbe4a..cf4dcdd555 100644 --- a/libs/freetdm/src/include/ftdm_declare.h +++ b/libs/freetdm/src/include/ftdm_declare.h @@ -203,6 +203,14 @@ typedef enum { FTDM_TRUE } ftdm_bool_t; +/*! \brief I/O waiting flags */ +typedef enum { + FTDM_NO_FLAGS = 0, + FTDM_READ = (1 << 0), + FTDM_WRITE = (1 << 1), + FTDM_EVENTS = (1 << 2) +} ftdm_wait_flag_t; + /*! * \brief FreeTDM channel. * This is the basic data structure used to place calls and I/O operations diff --git a/libs/freetdm/src/include/ftdm_threadmutex.h b/libs/freetdm/src/include/ftdm_threadmutex.h index 2e802fe913..b77f19f4bb 100644 --- a/libs/freetdm/src/include/ftdm_threadmutex.h +++ b/libs/freetdm/src/include/ftdm_threadmutex.h @@ -52,11 +52,12 @@ FT_DECLARE(ftdm_status_t) _ftdm_mutex_trylock(const char *file, int line, const #define ftdm_mutex_unlock(_x) _ftdm_mutex_unlock(__FILE__, __LINE__, __FUNCTION__, _x) FT_DECLARE(ftdm_status_t) _ftdm_mutex_unlock(const char *file, int line, const char *func, ftdm_mutex_t *mutex); -FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **cond, ftdm_socket_t device); +FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **cond, ftdm_socket_t device, ftdm_wait_flag_t device_flags); FT_DECLARE(ftdm_status_t) ftdm_interrupt_destroy(ftdm_interrupt_t **cond); FT_DECLARE(ftdm_status_t) ftdm_interrupt_signal(ftdm_interrupt_t *cond); FT_DECLARE(ftdm_status_t) ftdm_interrupt_wait(ftdm_interrupt_t *cond, int ms); FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interrupts[], ftdm_size_t size, int ms); +FT_DECLARE(ftdm_wait_flag_t) ftdm_interrupt_device_ready(ftdm_interrupt_t *interrupt); #ifdef __cplusplus }