[asterisk-commits] mmichelson: branch group/CCSS r215214 - in /team/group/CCSS: include/asterisk...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Sep 1 16:06:24 CDT 2009
Author: mmichelson
Date: Tue Sep 1 16:06:21 2009
New Revision: 215214
URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=215214
Log:
Provide means for monitors to register with the core.
This provides a way for a channel driver to register
a device monitor type so that the appropriate type
of monitor may be created when CC is requested. I need
to modify app_dial so that the frame data of an
AST_CONTROL_CC frame contains the type of monitor
that should be created.
A similar mechanism will be needed for agents, too.
I glossed over this step earlier since I am focusing
strictly on generic agents for now, though. With monitors
I can't do that though. It may be possible to combine
the registration of agents and monitors, although I don't
think I will do that just in case for some reason
someone should wish to only make a monitor or only
make an agent for a specific channel driver. Eh,
I'll think about it.
Modified:
team/group/CCSS/include/asterisk/ccss.h
team/group/CCSS/main/ccss.c
Modified: team/group/CCSS/include/asterisk/ccss.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/CCSS/include/asterisk/ccss.h?view=diff&rev=215214&r1=215213&r2=215214
==============================================================================
--- team/group/CCSS/include/asterisk/ccss.h (original)
+++ team/group/CCSS/include/asterisk/ccss.h Tue Sep 1 16:06:21 2009
@@ -480,6 +480,8 @@
};
struct ast_cc_monitor_callbacks {
+ /* Type of the monitor callbacks */
+ const char *type;
/* Allocate callback */
int (*init)(struct ast_cc_monitor *monitor, const int core_id);
/* Request CCSS callback */
@@ -490,8 +492,18 @@
enum ast_device_state(*status_request)(struct ast_cc_monitor *monitor, const int core_id);
/* Unsuspend monitoring callback */
int (*unsuspend)(struct ast_cc_monitor *monitor, const int core_id);
- /* Destroy callback (XXX handled in ao2 destructor?) */
- void (*destructor)(struct ast_cc_monitor *monitor, const int core_id);
+ /*!
+ * Destroy callback
+ *
+ * This destructor is never called directly. Instead, it is passed
+ * to the astobj2 system so that when the refcount for the monitor
+ * reaches zero, this function is called.
+ *
+ * The parameter is a void pointer since that is what ao2 requires
+ * for its destructors. However, the contents passed will always
+ * be a pointer to the monitor being destroyed.
+ */
+ void (*destructor)(void *monitor);
/* Pass status upstream callback (XXX ???) */
};
@@ -643,6 +655,20 @@
/*!
* \since 1.6.4
+ * \brief Register a set of monitor callbacks with the core
+ *
+ * This is made so that at monitor creation time, the proper callbacks
+ * may be installed and the proper .init callback may be called for the
+ * monitor to establish private data.
+ *
+ * \param callbacks The callbacks used by the monitor implementation
+ * \retval 0 Successfully registered
+ * \retval -1 Failure to register
+ */
+int ast_cc_monitor_register(const struct ast_cc_monitor_callbacks *callbacks);
+
+/*!
+ * \since 1.6.4
* \brief Initialize CCSS
*
* XXX This needs to be updated as more functionality is added.
Modified: team/group/CCSS/main/ccss.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/CCSS/main/ccss.c?view=diff&rev=215214&r1=215213&r2=215214
==============================================================================
--- team/group/CCSS/main/ccss.c (original)
+++ team/group/CCSS/main/ccss.c Tue Sep 1 16:06:21 2009
@@ -58,6 +58,14 @@
unsigned int cc_max_agents;
unsigned int cc_max_monitors;
char cc_callback_macro[AST_MAX_EXTENSION];
+};
+
+/* XXX Consider making this an RWLIST */
+AST_LIST_HEAD_STATIC(cc_monitor_backends, cc_monitor_backend);
+
+struct cc_monitor_backend {
+ AST_LIST_ENTRY(cc_monitor_backend) next;
+ const struct ast_cc_monitor_callbacks *callbacks;
};
/* XXX I'm making these defaults up right now with no real regard for
@@ -760,10 +768,39 @@
ast_free(agent_pvt);
}
-static struct ast_cc_monitor *cc_monitor_instance_init(enum ast_cc_monitor_type type, const char * const name)
-{
- /* STUB */
- return NULL;
+static const struct ast_cc_monitor_callbacks *find_monitor_callbacks(const char * const type)
+{
+ struct cc_monitor_backend *backend;
+ const struct ast_cc_monitor_callbacks *callbacks = NULL;
+
+ AST_LIST_LOCK(&cc_monitor_backends);
+ AST_LIST_TRAVERSE(&cc_monitor_backends, backend, next) {
+ if (!strcmp(backend->callbacks->type, type)) {
+ ast_log(LOG_NOTICE, "Returning backend %s\n", backend->callbacks->type);
+ callbacks = backend->callbacks;
+ break;
+ }
+ }
+ AST_LIST_UNLOCK(&cc_monitor_backends);
+ return callbacks;
+}
+
+static struct ast_cc_monitor *cc_monitor_instance_init(enum ast_cc_monitor_type type, const char * const callback_type, const char * const monitor_name, const int core_id)
+{
+ struct ast_cc_monitor *monitor;
+ const struct ast_cc_monitor_callbacks *callbacks = find_monitor_callbacks(callback_type);
+
+ ast_assert(callbacks != NULL);
+
+ if (!(monitor = ao2_alloc(sizeof(*monitor) + strlen(monitor_name), callbacks->destructor))) {
+ return NULL;
+ }
+
+ monitor->type = type;
+ strcpy(monitor->name, monitor_name);
+ monitor->callbacks = callbacks;
+ monitor->callbacks->init(monitor, core_id);
+ return monitor;
}
static int cc_monitor_tree_init(const int core_id)
@@ -778,8 +815,7 @@
* 1. Use the core_id to find the core instance
* and pending offer.
*
- * 2. Get a reference to the root monitor. This
- * may entail creating the root monitor.
+ * 2. Get a reference to the root monitor.
*
* 3. Morph the pending offer into a monitor
* tree. For each item in the pending offer's
@@ -984,9 +1020,10 @@
static int cc_extension_monitor_suspend(struct ast_cc_monitor *monitor, const int core_id);
static enum ast_device_state cc_extension_monitor_status_request(struct ast_cc_monitor *monitor, const int core_id);
static int cc_extension_monitor_unsuspend(struct ast_cc_monitor *monitor, const int core_id);
-static void cc_extension_monitor_destructor(struct ast_cc_monitor *monitor, const int core_id);
+static void cc_extension_monitor_destructor(void *monitor);
static struct ast_cc_monitor_callbacks extension_monitor_cbs = {
+ .type = "extension",
.init = cc_extension_monitor_init,
.request_cc = cc_extension_monitor_request_cc,
.suspend = cc_extension_monitor_suspend,
@@ -1025,10 +1062,26 @@
return 0;
}
-static void cc_extension_monitor_destructor(struct ast_cc_monitor *monitor, const int core_id)
+static void cc_extension_monitor_destructor(void *monitor)
{
/* STUB */
return;
+}
+
+int ast_cc_monitor_register(const struct ast_cc_monitor_callbacks *callbacks)
+{
+ struct cc_monitor_backend *backend = ast_calloc(1, sizeof(*backend));
+
+ if (!backend) {
+ return -1;
+ }
+
+ backend->callbacks = callbacks;
+
+ AST_LIST_LOCK(&cc_monitor_backends);
+ AST_LIST_INSERT_TAIL(&cc_monitor_backends, backend, next);
+ AST_LIST_UNLOCK(&cc_monitor_backends);
+ return 0;
}
int ast_cc_init(void)
@@ -1052,11 +1105,16 @@
if (!(cc_sched_thread = ast_sched_thread_create())) {
return -1;
}
- if (!(root_monitor = cc_monitor_instance_init(AST_CC_ROOT_MONITOR, "root"))) {
+ /* Root monitor doesn't care about the core id. The root monitor uses
+ * extension monitor callbacks since the gist of those will be to traverse
+ * their child links and call each of their children's callbacks
+ */
+ if (!(root_monitor = cc_monitor_instance_init(AST_CC_ROOT_MONITOR, "extension", "root", -1))) {
return -1;
}
ast_log(LOG_NOTICE, "Successfully created CC sched_thread context\n");
res = ast_register_application2(ccreq_app, ccreq_exec, NULL, NULL, NULL);
res |= ast_register_application2(cccancel_app, cccancel_exec, NULL, NULL, NULL);
+ res |= ast_cc_monitor_register(&extension_monitor_cbs);
return res;
}
More information about the asterisk-commits
mailing list