[asterisk-commits] russell: branch russell/event_performance r183662 - in /team/russell/event_pe...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sun Mar 22 16:19:07 CDT 2009
Author: russell
Date: Sun Mar 22 16:19:02 2009
New Revision: 183662
URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=183662
Log:
save off some progress on the next thing i'm doing ..
Modified:
team/russell/event_performance/apps/app_voicemail.c
team/russell/event_performance/channels/chan_dahdi.c
team/russell/event_performance/include/asterisk/_private.h
team/russell/event_performance/include/asterisk/event.h
team/russell/event_performance/main/asterisk.c
team/russell/event_performance/main/devicestate.c
team/russell/event_performance/main/event.c
team/russell/event_performance/res/ais/evt.c
Modified: team/russell/event_performance/apps/app_voicemail.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/event_performance/apps/app_voicemail.c?view=diff&rev=183662&r1=183661&r2=183662
==============================================================================
--- team/russell/event_performance/apps/app_voicemail.c (original)
+++ team/russell/event_performance/apps/app_voicemail.c Sun Mar 22 16:19:02 2009
@@ -6092,10 +6092,7 @@
return;
}
- ast_event_queue_and_cache(event,
- AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR,
- AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR,
- AST_EVENT_IE_END);
+ ast_event_queue_and_cache(event);
}
/*!
Modified: team/russell/event_performance/channels/chan_dahdi.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/event_performance/channels/chan_dahdi.c?view=diff&rev=183662&r1=183661&r2=183662
==============================================================================
--- team/russell/event_performance/channels/chan_dahdi.c (original)
+++ team/russell/event_performance/channels/chan_dahdi.c Sun Mar 22 16:19:02 2009
@@ -2305,10 +2305,7 @@
return;
}
- ast_event_queue_and_cache(event,
- AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR,
- AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR,
- AST_EVENT_IE_END);
+ ast_event_queue_and_cache(event);
if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(mwimonitornotify)) {
snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot);
Modified: team/russell/event_performance/include/asterisk/_private.h
URL: http://svn.digium.com/svn-view/asterisk/team/russell/event_performance/include/asterisk/_private.h?view=diff&rev=183662&r1=183661&r2=183662
==============================================================================
--- team/russell/event_performance/include/asterisk/_private.h (original)
+++ team/russell/event_performance/include/asterisk/_private.h Sun Mar 22 16:19:02 2009
@@ -28,7 +28,7 @@
void dnsmgr_start_refresh(void); /*!< Provided by dnsmgr.c */
int dnsmgr_reload(void); /*!< Provided by dnsmgr.c */
void threadstorage_init(void); /*!< Provided by threadstorage.c */
-void ast_event_init(void); /*!< Provided by event.c */
+int ast_event_init(void); /*!< Provided by event.c */
int ast_device_state_engine_init(void); /*!< Provided by devicestate.c */
int astobj2_init(void); /*!< Provided by astobj2.c */
int ast_file_init(void); /*!< Provided by file.c */
Modified: team/russell/event_performance/include/asterisk/event.h
URL: http://svn.digium.com/svn-view/asterisk/team/russell/event_performance/include/asterisk/event.h?view=diff&rev=183662&r1=183661&r2=183662
==============================================================================
--- team/russell/event_performance/include/asterisk/event.h (original)
+++ team/russell/event_performance/include/asterisk/event.h Sun Mar 22 16:19:02 2009
@@ -392,8 +392,10 @@
* The purpose of caching events is so that the core can retain the last known
* information for events that represent some sort of state. That way, when
* code needs to find out the current state, it can query the cache.
- */
-int ast_event_queue_and_cache(struct ast_event *event, ...);
+ *
+ * XXX FIX DOCS XXX
+ */
+int ast_event_queue_and_cache(struct ast_event *event);
/*!
* \brief Retrieve an event from the cache
Modified: team/russell/event_performance/main/asterisk.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/event_performance/main/asterisk.c?view=diff&rev=183662&r1=183661&r2=183662
==============================================================================
--- team/russell/event_performance/main/asterisk.c (original)
+++ team/russell/event_performance/main/asterisk.c Sun Mar 22 16:19:02 2009
@@ -3343,7 +3343,10 @@
}
#endif
- ast_event_init();
+ if (ast_event_init()) {
+ printf("%s", term_quit());
+ exit(1);
+ }
ast_makesocket();
sigemptyset(&sigs);
Modified: team/russell/event_performance/main/devicestate.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/event_performance/main/devicestate.c?view=diff&rev=183662&r1=183661&r2=183662
==============================================================================
--- team/russell/event_performance/main/devicestate.c (original)
+++ team/russell/event_performance/main/devicestate.c Sun Mar 22 16:19:02 2009
@@ -473,18 +473,7 @@
return;
}
- /* Cache this event, replacing an event in the cache with the same
- * device name if it exists. */
- if (event_type == AST_EVENT_DEVICE_STATE_CHANGE) {
- ast_event_queue_and_cache(event,
- AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR,
- AST_EVENT_IE_EID, AST_EVENT_IE_PLTYPE_RAW, sizeof(struct ast_eid),
- AST_EVENT_IE_END);
- } else {
- ast_event_queue_and_cache(event,
- AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR,
- AST_EVENT_IE_END);
- }
+ ast_event_queue_and_cache(event);
}
/*! Called by the state change thread to find out what the state is, and then
@@ -673,13 +662,12 @@
AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device,
AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, state,
AST_EVENT_IE_END);
-
- if (!event)
+
+ if (!event) {
return;
-
- ast_event_queue_and_cache(event,
- AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR,
- AST_EVENT_IE_END);
+ }
+
+ ast_event_queue_and_cache(event);
}
static void handle_devstate_change(struct devstate_change *sc)
Modified: team/russell/event_performance/main/event.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/event_performance/main/event.c?view=diff&rev=183662&r1=183661&r2=183662
==============================================================================
--- team/russell/event_performance/main/event.c (original)
+++ team/russell/event_performance/main/event.c Sun Mar 22 16:19:02 2009
@@ -28,6 +28,7 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/_private.h"
+
#include "asterisk/event.h"
#include "asterisk/linkedlists.h"
#include "asterisk/dlinkedlists.h"
@@ -36,6 +37,7 @@
#include "asterisk/unaligned.h"
#include "asterisk/utils.h"
#include "asterisk/taskprocessor.h"
+#include "asterisk/astobj2.h"
struct ast_taskprocessor *event_dispatcher;
@@ -115,11 +117,41 @@
* The event subscribers are indexed by which event they are subscribed to */
static AST_RWDLLIST_HEAD(ast_event_sub_list, ast_event_sub) ast_event_subs[AST_EVENT_TOTAL];
-/*! \brief Cached events
- * The event cache is indexed on the event type. The purpose of this is
- * for events that express some sort of state. So, when someone first
- * needs to know this state, it can get the last known state from the cache. */
-static AST_RWLIST_HEAD(ast_event_ref_list, ast_event_ref) ast_event_cache[AST_EVENT_TOTAL];
+static struct ao2_container *ast_event_cache[AST_EVENT_TOTAL];
+
+#ifdef LOW_MEMORY
+#define NUM_CACHE_BUCKETS 17
+#else
+#define NUM_CACHE_BUCKETS 563
+#endif
+
+static int ast_event_hash_mwi(const void *obj, const int flags);
+static int ast_event_cmp_mwi(void *obj, void *arg, int flags);
+static int ast_event_hash_devstate(const void *obj, const int flags);
+static int ast_event_cmp_devstate(void *obj, void *arg, int flags);
+static int ast_event_hash_devstate_change(const void *obj, const int flags);
+static int ast_event_cmp_devstate_change(void *obj, void *arg, int flags);
+
+/*!
+ * \brief Event types that are kept in the cache.
+ */
+static const struct {
+ ao2_hash_fn *hash_fn;
+ ao2_callback_fn *cmp_fn;
+} cached_event_types[AST_EVENT_TOTAL] = {
+ [AST_EVENT_MWI] = {
+ .hash_fn = ast_event_hash_mwi,
+ .cmp_fn = ast_event_cmp_mwi,
+ },
+ [AST_EVENT_DEVICE_STATE] = {
+ .hash_fn = ast_event_hash_devstate,
+ .cmp_fn = ast_event_cmp_devstate,
+ },
+ [AST_EVENT_DEVICE_STATE_CHANGE] = {
+ .hash_fn = ast_event_hash_devstate_change,
+ .cmp_fn = ast_event_cmp_devstate_change,
+ },
+};
/*!
* The index of each entry _must_ match the event type number!
@@ -381,6 +413,7 @@
/*! \brief Dump the event cache for the subscribed event type */
void ast_event_dump_cache(const struct ast_event_sub *event_sub)
{
+#if 0
struct ast_event_ref *event_ref;
enum ast_event_type type = event_sub->type;
@@ -398,6 +431,7 @@
}
AST_RWLIST_TRAVERSE_SAFE_END
AST_RWLIST_UNLOCK(&ast_event_cache[type]);
+#endif
}
static struct ast_event *gen_sub_event(struct ast_event_sub *sub)
@@ -896,10 +930,11 @@
ast_free(event);
}
-static void ast_event_ref_destroy(struct ast_event_ref *event_ref)
-{
+static void ast_event_ref_destroy(void *obj)
+{
+ struct ast_event_ref *event_ref = obj;
+
ast_event_destroy(event_ref->event);
- ast_free(event_ref);
}
static struct ast_event *ast_event_dup(const struct ast_event *event)
@@ -909,9 +944,10 @@
event_len = ast_event_get_size(event);
- if (!(dup_event = ast_calloc(1, event_len)))
+ if (!(dup_event = ast_calloc(1, event_len))) {
return NULL;
-
+ }
+
memcpy(dup_event, event, event_len);
return dup_event;
@@ -922,7 +958,7 @@
va_list ap;
enum ast_event_ie_type ie_type;
struct ast_event *dup_event = NULL;
- struct ast_event_ref *event_ref;
+ //struct ast_event_ref *event_ref;
struct ast_event_ie_val *cache_arg;
AST_LIST_HEAD_NOLOCK_STATIC(cache_args, ast_event_ie_val);
@@ -960,7 +996,7 @@
"specifying at least one IE type!\n");
return NULL;
}
-
+#if 0
AST_RWLIST_RDLOCK(&ast_event_cache[type]);
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&ast_event_cache[type], event_ref, entry) {
AST_LIST_TRAVERSE(&cache_args, cache_arg, entry) {
@@ -975,86 +1011,64 @@
}
AST_RWLIST_TRAVERSE_SAFE_END
AST_RWLIST_UNLOCK(&ast_event_cache[type]);
-
+#endif
return dup_event;
+}
+
+static struct ast_event_ref *alloc_event_ref(void)
+{
+ return ao2_alloc(sizeof(struct ast_event_ref), ast_event_ref_destroy);
}
/*! \brief Duplicate an event and add it to the cache
* \note This assumes this index in to the cache is locked */
-static int ast_event_dup_and_cache(const struct ast_event *event)
+static int attribute_unused ast_event_dup_and_cache(const struct ast_event *event)
{
struct ast_event *dup_event;
struct ast_event_ref *event_ref;
- if (!(dup_event = ast_event_dup(event)))
- return -1;
- if (!(event_ref = ast_calloc(1, sizeof(*event_ref))))
- return -1;
-
+ if (!(dup_event = ast_event_dup(event))) {
+ return -1;
+ }
+
+ if (!(event_ref = alloc_event_ref())) {
+ return -1;
+ }
+
event_ref->event = dup_event;
- AST_LIST_INSERT_TAIL(&ast_event_cache[ntohs(event->type)], event_ref, entry);
-
- return 0;
-}
-
-int ast_event_queue_and_cache(struct ast_event *event, ...)
-{
- va_list ap;
- enum ast_event_type ie_type;
- uint16_t host_event_type;
+ ao2_link(ast_event_cache[ast_event_get_type(event)], event_ref);
+
+ ao2_ref(event_ref, -1);
+
+ return 0;
+}
+
+int ast_event_queue_and_cache(struct ast_event *event)
+{
struct ast_event_ref *event_ref;
- int res;
- struct ast_event_ie_val *cache_arg;
- AST_LIST_HEAD_NOLOCK_STATIC(cache_args, ast_event_ie_val);
-
- host_event_type = ntohs(event->type);
-
- /* Invalid type */
- if (host_event_type >= AST_EVENT_TOTAL) {
- ast_log(LOG_WARNING, "Someone tried to queue an event of invalid "
- "type '%d'!\n", host_event_type);
- return -1;
- }
-
- va_start(ap, event);
- for (ie_type = va_arg(ap, enum ast_event_type);
- ie_type != AST_EVENT_IE_END;
- ie_type = va_arg(ap, enum ast_event_type))
- {
- cache_arg = alloca(sizeof(*cache_arg));
- memset(cache_arg, 0, sizeof(*cache_arg));
- cache_arg->ie_type = ie_type;
- cache_arg->ie_pltype = va_arg(ap, enum ast_event_ie_pltype);
- if (cache_arg->ie_pltype == AST_EVENT_IE_PLTYPE_RAW)
- cache_arg->raw_datalen = va_arg(ap, size_t);
- AST_LIST_INSERT_TAIL(&cache_args, cache_arg, entry);
- }
- va_end(ap);
-
- if (AST_LIST_EMPTY(&cache_args)) {
- ast_log(LOG_ERROR, "Events can not be cached without specifying at "
- "least one IE type!\n");
- return ast_event_queue(event);
- }
-
- AST_RWLIST_WRLOCK(&ast_event_cache[host_event_type]);
- AST_RWLIST_TRAVERSE_SAFE_BEGIN(&ast_event_cache[host_event_type], event_ref, entry) {
- AST_LIST_TRAVERSE(&cache_args, cache_arg, entry) {
- if (!match_ie_val(event_ref->event, cache_arg, event))
- break;
- }
- if (!cache_arg) {
- /* All parameters were matched on this cache entry, so remove it */
- AST_LIST_REMOVE_CURRENT(entry);
- ast_event_ref_destroy(event_ref);
- }
- }
- AST_RWLIST_TRAVERSE_SAFE_END;
- res = ast_event_dup_and_cache(event);
- AST_RWLIST_UNLOCK(&ast_event_cache[host_event_type]);
-
- return (ast_event_queue(event) || res) ? -1 : 0;
+ ao2_callback_fn *cb_fn;
+ struct ao2_container *container;
+ struct ast_event_ref tmp_event_ref = {
+ .event = event,
+ };
+
+ if (!(container = ast_event_cache[ast_event_get_type(event)])) {
+ goto queue_event;
+ }
+
+ if (!(cb_fn = cached_event_types[ast_event_get_type(event)].cmp_fn)) {
+ goto queue_event;
+ }
+
+ /* Remove matches from the cache */
+ while ((event_ref = ao2_callback(container, OBJ_POINTER | OBJ_UNLINK,
+ cb_fn, &tmp_event_ref))) {
+ ao2_ref(event_ref, -1);
+ }
+
+queue_event:
+ return ast_event_queue(event);
}
static int handle_event(void *data)
@@ -1070,22 +1084,25 @@
AST_RWDLLIST_TRAVERSE(&ast_event_subs[host_event_type], sub, entry) {
struct ast_event_ie_val *ie_val;
AST_LIST_TRAVERSE(&sub->ie_vals, ie_val, entry) {
- if (!match_ie_val(event_ref->event, ie_val, NULL))
+ if (!match_ie_val(event_ref->event, ie_val, NULL)) {
break;
- }
- if (ie_val)
+ }
+ }
+ if (ie_val) {
continue;
+ }
sub->cb(event_ref->event, sub->userdata);
}
AST_RWDLLIST_UNLOCK(&ast_event_subs[host_event_type]);
/* Now to subscribers to all event types */
AST_RWDLLIST_RDLOCK(&ast_event_subs[AST_EVENT_ALL]);
- AST_RWDLLIST_TRAVERSE(&ast_event_subs[AST_EVENT_ALL], sub, entry)
+ AST_RWDLLIST_TRAVERSE(&ast_event_subs[AST_EVENT_ALL], sub, entry) {
sub->cb(event_ref->event, sub->userdata);
+ }
AST_RWDLLIST_UNLOCK(&ast_event_subs[AST_EVENT_ALL]);
- ast_event_ref_destroy(event_ref);
+ ao2_ref(event_ref, -1);
return 0;
}
@@ -1105,29 +1122,123 @@
}
/* If nobody has subscribed to this event type, throw it away now */
- if (ast_event_check_subscriber(host_event_type, AST_EVENT_IE_END)
- == AST_EVENT_SUB_NONE) {
+ if (ast_event_check_subscriber(host_event_type, AST_EVENT_IE_END)
+ == AST_EVENT_SUB_NONE) {
ast_event_destroy(event);
return 0;
}
- if (!(event_ref = ast_calloc(1, sizeof(*event_ref))))
- return -1;
+ if (!(event_ref = ast_calloc(1, sizeof(*event_ref)))) {
+ return -1;
+ }
event_ref->event = event;
return ast_taskprocessor_push(event_dispatcher, handle_event, event_ref);
}
-void ast_event_init(void)
+static int ast_event_hash_mwi(const void *obj, const int flags)
+{
+ const struct ast_event *event = obj;
+ const char *mailbox = ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX);
+ const char *context = ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT);
+ struct ast_str *str;
+
+ str = ast_str_alloca(strlen(mailbox) + strlen(context) + 1);
+
+ ast_str_set(&str, 0, "%s@%s", mailbox, context);
+
+ return ast_str_hash(ast_str_buffer(str));
+}
+
+static int ast_event_cmp_mwi(void *obj, void *arg, int flags)
+{
+ /* XXX */
+ return 0;
+}
+
+static int ast_event_hash_devstate(const void *obj, const int flags)
+{
+ /* XXX */
+ return 0;
+}
+
+static int ast_event_cmp_devstate(void *obj, void *arg, int flags)
+{
+ /* XXX */
+ return 0;
+}
+
+static int ast_event_hash_devstate_change(const void *obj, const int flags)
+{
+ /* XXX */
+ return 0;
+}
+
+static int ast_event_cmp_devstate_change(void *obj, void *arg, int flags)
+{
+ /* XXX */
+ return 0;
+}
+
+static int ast_event_hash(const void *obj, const int flags)
+{
+ const struct ast_event_ref *event_ref;
+ const struct ast_event *event;
+ ao2_hash_fn *hash_fn;
+
+ event_ref = obj;
+ event = event_ref->event;
+
+ if (!(hash_fn = cached_event_types[ast_event_get_type(event)].hash_fn)) {
+ return 0;
+ }
+
+ return hash_fn(event, flags);
+}
+
+static int ast_event_cmp(void *obj, void *arg, int flags)
+{
+ struct ast_event_ref *event_ref, *event_ref2;
+ struct ast_event *event, *event2;
+ ao2_callback_fn *cmp_fn;
+
+ event_ref = obj;
+ event = event_ref->event;
+
+ event_ref2 = arg;
+ event2 = event_ref2->event;
+
+ if (!(cmp_fn = cached_event_types[ast_event_get_type(event)].cmp_fn)) {
+ return 0;
+ }
+
+ return cmp_fn(event, event2, flags);
+}
+
+int ast_event_init(void)
{
int i;
- for (i = 0; i < AST_EVENT_TOTAL; i++)
+ for (i = 0; i < AST_EVENT_TOTAL; i++) {
AST_RWDLLIST_HEAD_INIT(&ast_event_subs[i]);
-
- for (i = 0; i < AST_EVENT_TOTAL; i++)
- AST_RWLIST_HEAD_INIT(&ast_event_cache[i]);
-
- event_dispatcher = ast_taskprocessor_get("core_event_dispatcher", 0);
-}
+ }
+
+ for (i = 0; i < AST_EVENT_TOTAL; i++) {
+ if (!cached_event_types[i].hash_fn) {
+ /* This event type is not cached. */
+ continue;
+ }
+
+ if (!(ast_event_cache[i] = ao2_container_alloc(NUM_CACHE_BUCKETS,
+ ast_event_hash, ast_event_cmp))) {
+ return -1;
+ }
+ }
+
+ if (!(event_dispatcher = ast_taskprocessor_get("core_event_dispatcher", 0))) {
+ return -1;
+ }
+
+ return 0;
+}
Modified: team/russell/event_performance/res/ais/evt.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/event_performance/res/ais/evt.c?view=diff&rev=183662&r1=183661&r2=183662
==============================================================================
--- team/russell/event_performance/res/ais/evt.c (original)
+++ team/russell/event_performance/res/ais/evt.c Sun Mar 22 16:19:02 2009
@@ -112,34 +112,7 @@
static void queue_event(struct ast_event *ast_event)
{
- enum ast_event_type type;
-
- /*!
- * \todo This hack macks me sad. I need to come up with a better way to
- * figure out whether an event should be cached or not, and what
- * parameters to cache on.
- *
- * As long as the types of events that are supported is limited,
- * this isn't *terrible*, I guess. Perhaps we should just define
- * caching rules in the core, and make them configurable, and not
- * have it be the job of the event publishers.
- */
-
- type = ast_event_get_type(ast_event);
-
- if (type == AST_EVENT_MWI) {
- ast_event_queue_and_cache(ast_event,
- AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR,
- AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR,
- AST_EVENT_IE_END);
- } else if (type == AST_EVENT_DEVICE_STATE_CHANGE) {
- ast_event_queue_and_cache(ast_event,
- AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR,
- AST_EVENT_IE_EID, AST_EVENT_IE_PLTYPE_RAW, sizeof(struct ast_eid),
- AST_EVENT_IE_END);
- } else {
- ast_event_queue(ast_event);
- }
+ ast_event_queue_and_cache(ast_event);
}
void evt_event_deliver_cb(SaEvtSubscriptionIdT sub_id,
More information about the asterisk-commits
mailing list