diff --git a/src/include/switch_event.h b/src/include/switch_event.h index 0cb83fb397..d19b47ca6f 100644 --- a/src/include/switch_event.h +++ b/src/include/switch_event.h @@ -38,28 +38,34 @@ extern "C" { #include +struct switch_event_subclass { + char *owner; + char *name; +}; + struct switch_event { switch_event_t event; - int subclass; + switch_event_subclass *subclass; char *data; + void *user_data; struct switch_event *next; }; struct switch_event_node { char *id; switch_event_t event; - int subclass; + switch_event_subclass *subclass; switch_event_callback_t callback; + void *user_data; struct switch_event_node *next; }; SWITCH_DECLARE(switch_status) switch_event_shutdown(void); SWITCH_DECLARE(switch_status) switch_event_init(switch_memory_pool *pool); -SWITCH_DECLARE(switch_status) switch_event_fire_subclass(switch_event_t event, int subclass, char *data); -SWITCH_DECLARE(switch_status) switch_event_bind(char *id, switch_event_t event, int subclass, switch_event_callback_t callback); +SWITCH_DECLARE(switch_status) switch_event_fire_subclass(switch_event_t event, char *subclass_name, char *data); +SWITCH_DECLARE(switch_status) switch_event_bind(char *id, switch_event_t event, char *subclass_name, switch_event_callback_t callback, void *user_data); SWITCH_DECLARE(char *) switch_event_name(switch_event_t event); -SWITCH_DECLARE(char *) switch_event_subclass_name(int subclass); -SWITCH_DECLARE(switch_status) switch_event_reserve_subclass(int subclass, char *name); -#define switch_event_fire(event, data) switch_event_fire_subclass(event, 0, data); - +SWITCH_DECLARE(switch_status) switch_event_reserve_subclass_detailed(char *owner, char *subclass_name); +#define switch_event_fire(event, data) switch_event_fire_subclass(event, NULL, data); +#define switch_event_reserve_subclass(subclass_name) switch_event_reserve_subclass_detailed(__FILE__, subclass_name) #endif diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 575362f5f3..f993e1df00 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -139,6 +139,7 @@ typedef enum { } switch_event_t; typedef struct switch_event switch_event; +typedef struct switch_event_subclass switch_event_subclass; typedef struct switch_event_node switch_event_node; typedef void (*switch_event_callback_t)(switch_event *); typedef apr_threadattr_t switch_threadattr_t; diff --git a/src/mod/mod_event_test/mod_event_test.c b/src/mod/mod_event_test/mod_event_test.c index c84f3ff1ef..613e451145 100644 --- a/src/mod/mod_event_test/mod_event_test.c +++ b/src/mod/mod_event_test/mod_event_test.c @@ -31,19 +31,14 @@ */ #include -typedef enum { - MY_EVENT_UNDEF, - MY_EVENT_COOL -} my_event_t; - static const char modname[] = "mod_event_test"; static void event_handler (switch_event *event) { - switch_console_printf(SWITCH_CHANNEL_CONSOLE,"*** OK *** I got event [%s] subclass [%d(%s)] data [%s]\n", + switch_console_printf(SWITCH_CHANNEL_CONSOLE,"\n*** EVENT ***\nEventName: %s\nSubclassOwner: %s\nSubclassName: %s\nEventData: %s\n\n", switch_event_name(event->event), - event->subclass, - switch_event_subclass_name(event->subclass), + event->subclass->owner, + event->subclass->name, event->data); } @@ -56,15 +51,17 @@ static switch_loadable_module_interface event_test_module_interface = { /*.application_interface*/ NULL }; +#define MY_EVENT_COOL "test::cool" + SWITCH_MOD_DECLARE(switch_status) switch_module_load(switch_loadable_module_interface **interface, char *filename) { /* connect my internal structure to the blank pointer passed to me */ *interface = &event_test_module_interface; - if (switch_event_reserve_subclass(MY_EVENT_COOL, "my cool event") != SWITCH_STATUS_SUCCESS) { + if (switch_event_reserve_subclass(MY_EVENT_COOL) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Couldn't register subclass!"); return SWITCH_STATUS_GENERR; } - switch_event_bind((char *)modname, SWITCH_EVENT_ALL, -1, event_handler); + switch_event_bind((char *)modname, SWITCH_EVENT_ALL, NULL, event_handler, NULL); /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; diff --git a/src/mod/mod_portaudio/mod_portaudio.c b/src/mod/mod_portaudio/mod_portaudio.c index bfe421fc11..4d19ef9a8b 100644 --- a/src/mod/mod_portaudio/mod_portaudio.c +++ b/src/mod/mod_portaudio/mod_portaudio.c @@ -37,7 +37,7 @@ #include "pablio.h" #include -#define MY_EVENT_RINGING 100 +#define MY_EVENT_RINGING "portaudio::ringing" static const char modname[] = "mod_portaudio"; @@ -506,7 +506,7 @@ SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_modul dump_info(); - if (switch_event_reserve_subclass(MY_EVENT_RINGING, "SoundCard Ringing") != SWITCH_STATUS_SUCCESS) { + if (switch_event_reserve_subclass(MY_EVENT_RINGING) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Couldn't register subclass!"); return SWITCH_STATUS_GENERR; } diff --git a/src/switch_event.c b/src/switch_event.c index d0d3091f4b..908f2c8248 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -56,9 +56,35 @@ static char *EVENT_NAMES[] = { "ALL" }; +static struct switch_event_subclass default_subclass = {__FILE__, "NONE"}; + +static int switch_events_match(switch_event *event, switch_event_node *node) +{ + int match = 0; + + + if (node->event == SWITCH_EVENT_ALL) { + return 1; + } + + if (event->event == node->event) { + + if (node->subclass) { + match = (event->subclass && strstr(event->subclass->name, node->subclass->name)); + } else if (event->subclass) { + match = 0; + } + + } + + + return match; + +} + static void * SWITCH_THREAD_FUNC switch_event_thread(switch_thread *thread, void *obj) { - switch_event_node *enp; + switch_event_node *node; switch_event *event = NULL, *out_event = NULL; switch_event_t e; switch_mutex_t *mutex = NULL; @@ -85,9 +111,13 @@ static void * SWITCH_THREAD_FUNC switch_event_thread(switch_thread *thread, void event = event->next; out_event->next = NULL; for(e = out_event->event;; e = SWITCH_EVENT_ALL) { - for(enp = EVENT_NODES[e]; enp; enp = enp->next) { - if ((enp->event == out_event->event || enp->event == SWITCH_EVENT_ALL) && (enp->subclass == out_event->subclass || enp->subclass < 0)) { - enp->callback(out_event); + for(node = EVENT_NODES[e]; node; node = node->next) { + if (switch_events_match(out_event, node)) { + out_event->user_data = node->user_data; + if (!out_event->subclass) { + out_event->subclass = &default_subclass; + } + node->callback(out_event); } } @@ -107,6 +137,7 @@ static void * SWITCH_THREAD_FUNC switch_event_thread(switch_thread *thread, void } + SWITCH_DECLARE(char *) switch_event_name(switch_event_t event) { assert(BLOCK != NULL); @@ -115,41 +146,26 @@ SWITCH_DECLARE(char *) switch_event_name(switch_event_t event) return EVENT_NAMES[event]; } -SWITCH_DECLARE(char *) switch_event_subclass_name(int subclass) +SWITCH_DECLARE(switch_status) switch_event_reserve_subclass_detailed(char *owner, char *subclass_name) { - char *name; - char val[50] = ""; - - assert(EPOOL != NULL); - assert(CUSTOM_HASH != NULL); - if (subclass <= 0) { - return "NONE"; - } - - snprintf(val, sizeof(val), "%d", subclass); - name = switch_core_hash_find(CUSTOM_HASH, val); - return name ? name : "UNRESERVED"; -} - - -SWITCH_DECLARE(switch_status) switch_event_reserve_subclass(int subclass, char *name) -{ - char val[50] = ""; + switch_event_subclass *subclass; assert(EPOOL != NULL); assert(CUSTOM_HASH != NULL); - if (subclass <= 0) { - return SWITCH_STATUS_NOTIMPL; - } - - snprintf(val, sizeof(val), "%d", subclass); - if (switch_core_hash_find(CUSTOM_HASH, val)) { + if (switch_core_hash_find(CUSTOM_HASH, subclass_name)) { return SWITCH_STATUS_INUSE; } + + if (!(subclass = switch_core_alloc(EPOOL, sizeof(*subclass)))) { + return SWITCH_STATUS_MEMERR; + } + + subclass->owner = switch_core_strdup(EPOOL, owner); + subclass->name = switch_core_strdup(EPOOL, subclass_name); - switch_core_hash_insert_dup(CUSTOM_HASH, val, switch_core_strdup(EPOOL, name)); + switch_core_hash_insert_dup(CUSTOM_HASH, subclass->name, subclass); return SWITCH_STATUS_SUCCESS; @@ -173,7 +189,6 @@ SWITCH_DECLARE(switch_status) switch_event_init(switch_memory_pool *pool) switch_threadattr_create(&thd_attr, pool); switch_threadattr_detach_set(thd_attr, 1); - assert(pool != NULL); EPOOL = pool; switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Eventing Engine.\n"); @@ -194,10 +209,11 @@ SWITCH_DECLARE(switch_status) switch_event_init(switch_memory_pool *pool) } -SWITCH_DECLARE(switch_status) switch_event_fire_subclass(switch_event_t event, int subclass, char *data) +SWITCH_DECLARE(switch_status) switch_event_fire_subclass(switch_event_t event, char *subclass_name, char *data) { switch_event *new_event, *ep; + switch_event_subclass *subclass = NULL; assert(BLOCK != NULL); assert(EPOOL != NULL); @@ -206,6 +222,10 @@ SWITCH_DECLARE(switch_status) switch_event_fire_subclass(switch_event_t event, i return SWITCH_STATUS_MEMERR; } + if (subclass_name) { + subclass = switch_core_hash_find(CUSTOM_HASH, subclass_name); + } + memset(new_event, 0, sizeof(*new_event)); new_event->event = event; new_event->subclass = subclass; @@ -222,17 +242,25 @@ SWITCH_DECLARE(switch_status) switch_event_fire_subclass(switch_event_t event, i } switch_mutex_unlock(QLOCK); /* -----------------------------------------------*/ + switch_thread_cond_signal(COND); return SWITCH_STATUS_SUCCESS; } -SWITCH_DECLARE(switch_status) switch_event_bind(char *id, switch_event_t event, int subclass, switch_event_callback_t callback) +SWITCH_DECLARE(switch_status) switch_event_bind(char *id, switch_event_t event, char *subclass_name, switch_event_callback_t callback, void *user_data) { switch_event_node *event_node; + switch_event_subclass *subclass = NULL; assert(BLOCK != NULL); assert(EPOOL != NULL); + if (subclass_name) { + if (!(subclass = switch_core_hash_find(CUSTOM_HASH, subclass_name))) { + return SWITCH_STATUS_FALSE; + } + } + if (event <= SWITCH_EVENT_ALL && (event_node = switch_core_alloc(EPOOL, sizeof(switch_event_node)))) { switch_mutex_lock(BLOCK); /* -----------------------------------------------*/ @@ -240,9 +268,12 @@ SWITCH_DECLARE(switch_status) switch_event_bind(char *id, switch_event_t event, event_node->event = event; event_node->subclass = subclass; event_node->callback = callback; + event_node->user_data = user_data; + if (EVENT_NODES[event]) { event_node->next = EVENT_NODES[event]; } + EVENT_NODES[event] = event_node; switch_mutex_unlock(BLOCK); /* -----------------------------------------------*/