[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