[asterisk-commits] branch file/datastores r10958 - in
/team/file/datastores: ./ include/asterisk/
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Thu Feb 23 16:36:31 MST 2006
Author: file
Date: Thu Feb 23 17:36:29 2006
New Revision: 10958
URL: http://svn.digium.com/view/asterisk?rev=10958&view=rev
Log:
Presenting channel datastores. This is a method of attaching complex (structures for example) data to a channel so it may be available at a later time. If it's not used, then a destroy callback is issued to free the memory upon channel hangup. Documentation coming soon!
Modified:
team/file/datastores/channel.c
team/file/datastores/include/asterisk/channel.h
Modified: team/file/datastores/channel.c
URL: http://svn.digium.com/view/asterisk/team/file/datastores/channel.c?rev=10958&r1=10957&r2=10958&view=diff
==============================================================================
--- team/file/datastores/channel.c (original)
+++ team/file/datastores/channel.c Thu Feb 23 17:36:29 2006
@@ -672,6 +672,7 @@
headp = &tmp->varshead;
ast_mutex_init(&tmp->lock);
AST_LIST_HEAD_INIT_NOLOCK(headp);
+ AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores);
strcpy(tmp->context, "default");
ast_string_field_set(tmp, language, defaultlanguage);
strcpy(tmp->exten, "s");
@@ -947,6 +948,7 @@
struct ast_var_t *vardata;
struct ast_frame *f, *fp;
struct varshead *headp;
+ struct ast_datastore *datastore = NULL;
char name[AST_CHANNEL_NAME];
headp=&chan->varshead;
@@ -1000,6 +1002,20 @@
ast_frfree(fp);
}
+ /* Get rid of each of the data stores on the channel */
+ AST_LIST_LOCK(&chan->datastores);
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, list) {
+ /* Remove from the list */
+ AST_LIST_REMOVE_CURRENT(&chan->datastores, list);
+ /* Lock it just in case someone else is using it (whyfor I don't know) */
+ ast_mutex_lock(&datastore->lock);
+ /* Free the data store */
+ ast_channel_datastore_free(datastore);
+ }
+ AST_LIST_TRAVERSE_SAFE_END
+ AST_LIST_UNLOCK(&chan->datastores);
+ AST_LIST_HEAD_DESTROY(&chan->datastores);
+
/* loop over the variables list, freeing all data and deleting list items */
/* no need to lock the list, as the channel is already locked */
@@ -1010,6 +1026,122 @@
AST_LIST_UNLOCK(&channels);
ast_device_state_changed_literal(name);
+}
+
+struct ast_datastore *ast_channel_datastore_alloc(char *type, char *uid)
+{
+ struct ast_datastore *datastore = NULL;
+
+ /* Make sure we at least have type so we can identify this */
+ if (type == NULL) {
+ return NULL;
+ }
+
+ /* Allocate memory for datastore and clear it */
+ datastore = ast_calloc(1, sizeof(*datastore));
+ if (datastore == NULL) {
+ return NULL;
+ }
+
+ /* Copy over data if applicable */
+ if (type != NULL) {
+ datastore->type = ast_strdup(type);
+ }
+ if (uid != NULL) {
+ datastore->uid = ast_strdup(uid);
+ }
+
+ /* Finish up by initializing the lock */
+ ast_mutex_init(&datastore->lock);
+
+ return datastore;
+}
+
+int ast_channel_datastore_free(struct ast_datastore *datastore)
+{
+ int res = 0;
+
+ /* Using the destroy function (if present) destroy the data */
+ if (datastore->destroy != NULL && datastore->data != NULL) {
+ datastore->destroy(datastore->data);
+ datastore->data = NULL;
+ }
+
+ /* Free allocated memory for type and UID if present */
+ if (datastore->type != NULL) {
+ free(datastore->type);
+ datastore->type = NULL;
+ }
+ if (datastore->uid != NULL) {
+ free(datastore->uid);
+ datastore->uid = NULL;
+ }
+
+ /* Destroy our lock */
+ ast_mutex_destroy(&datastore->lock);
+
+ /* Finally free memory used by ourselves */
+ free(datastore);
+ datastore = NULL;
+
+ return res;
+}
+
+int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
+{
+ int res = 0;
+
+ AST_LIST_LOCK(&chan->datastores);
+ AST_LIST_INSERT_HEAD(&chan->datastores, datastore, list);
+ AST_LIST_UNLOCK(&chan->datastores);
+
+ return res;
+}
+
+int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
+{
+ struct ast_datastore *datastore2 = NULL;
+ int res = -1;
+
+ /* Find our position and remove ourselves */
+ AST_LIST_LOCK(&chan->datastores);
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore2, list) {
+ if (datastore2 == datastore) {
+ AST_LIST_REMOVE_CURRENT(&chan->datastores, list);
+ res = 0;
+ break;
+ }
+ }
+ AST_LIST_TRAVERSE_SAFE_END
+ AST_LIST_UNLOCK(&chan->datastores);
+
+ return res;
+}
+
+struct ast_datastore *ast_channel_datastore_find(struct ast_channel *chan, char *type, char *uid)
+{
+ struct ast_datastore *datastore = NULL;
+
+ AST_LIST_LOCK(&chan->datastores);
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, list) {
+ if (type != NULL && datastore->type != NULL && !strcasecmp(type, datastore->type)) {
+ if (uid != NULL && datastore->uid != NULL) {
+ if (!strcasecmp(uid, datastore->uid)) {
+ /* Matched by type AND uid */
+ ast_mutex_lock(&datastore->lock);
+ break;
+ }
+ } else {
+ /* Matched by type at least */
+ ast_mutex_lock(&datastore->lock);
+ break;
+ }
+ }
+ }
+ AST_LIST_TRAVERSE_SAFE_END
+ AST_LIST_UNLOCK(&chan->datastores);
+
+ return datastore;
}
int ast_channel_spy_add(struct ast_channel *chan, struct ast_channel_spy *spy)
Modified: team/file/datastores/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/team/file/datastores/include/asterisk/channel.h?rev=10958&r1=10957&r2=10958&view=diff
==============================================================================
--- team/file/datastores/include/asterisk/channel.h (original)
+++ team/file/datastores/include/asterisk/channel.h Thu Feb 23 17:36:29 2006
@@ -144,6 +144,22 @@
int (*generate)(struct ast_channel *chan, void *data, int len, int samples);
};
+/*! Structure for a channel data store */
+struct ast_datastore {
+ /* Data store lock */
+ ast_mutex_t lock;
+ /*! Type of data store */
+ char *type;
+ /*! Unique data store identifier */
+ char *uid;
+ /*! Contained data */
+ void *data;
+ /*! Destroy function */
+ void (*destroy)(void *data);
+ /*! Used for easy linking */
+ AST_LIST_ENTRY(ast_datastore) list;
+};
+
/*! Structure for all kinds of caller ID identifications */
struct ast_callerid {
/*! Malloc'd Dialed Number Identifier */
@@ -425,6 +441,9 @@
/*! Chan Spy stuff */
struct ast_channel_spy_list *spies;
+ /*! Data stores on the channel */
+ AST_LIST_HEAD(datastores, ast_datastore) datastores;
+
/*! For easy linking */
AST_LIST_ENTRY(ast_channel) list;
};
@@ -555,6 +574,21 @@
CHANNEL_MANAGER_RELOAD,
};
+/*! \brief Create a channel datastore structure */
+struct ast_datastore *ast_channel_datastore_alloc(char *type, char *uid);
+
+/*! \brief Free a channel datastore structure */
+int ast_channel_datastore_free(struct ast_datastore *datastore);
+
+/*! \brief Add a datastore to a channel */
+int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore);
+
+/*! \brief Remove a datastore from a channel */
+int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore);
+
+/*! \brief Find a datastore on a channel */
+struct ast_datastore *ast_channel_datastore_find(struct ast_channel *chan, char *type, char *uid);
+
/*! \brief Change the state of a channel */
int ast_setstate(struct ast_channel *chan, int state);
More information about the asterisk-commits
mailing list