diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/Makefile | 2 | ||||
-rw-r--r-- | main/audiohook.c | 4 | ||||
-rw-r--r-- | main/channel.c | 66 | ||||
-rw-r--r-- | main/datastore.c | 73 | ||||
-rw-r--r-- | main/manager.c | 58 | ||||
-rw-r--r-- | main/pbx.c | 6 |
6 files changed, 151 insertions, 58 deletions
diff --git a/main/Makefile b/main/Makefile index a985819de..db4aad7e4 100644 --- a/main/Makefile +++ b/main/Makefile @@ -28,7 +28,7 @@ OBJS= tcptls.o io.o sched.o logger.o frame.o loader.o config.o channel.o \ cryptostub.o sha1.o http.o fixedjitterbuf.o abstract_jb.o \ strcompat.o threadstorage.o dial.o event.o adsistub.o audiohook.o \ astobj2.o hashtab.o global_datastores.o version.o \ - features.o taskprocessor.o timing.o + features.o taskprocessor.o timing.o datastore.o # we need to link in the objects statically, not as a library, because # otherwise modules will not have them available if none of the static diff --git a/main/audiohook.c b/main/audiohook.c index bd30ab772..2145154ae 100644 --- a/main/audiohook.c +++ b/main/audiohook.c @@ -843,13 +843,13 @@ static struct audiohook_volume *audiohook_volume_get(struct ast_channel *chan, i } /* If we are not allowed to create a datastore or if we fail to create a datastore, bail out now as we have nothing for them */ - if (!create || !(datastore = ast_channel_datastore_alloc(&audiohook_volume_datastore, NULL))) { + if (!create || !(datastore = ast_datastore_alloc(&audiohook_volume_datastore, NULL))) { return NULL; } /* Create a new audiohook_volume structure to contain our adjustments and audiohook */ if (!(audiohook_volume = ast_calloc(1, sizeof(*audiohook_volume)))) { - ast_channel_datastore_free(datastore); + ast_datastore_free(datastore); return NULL; } diff --git a/main/channel.c b/main/channel.c index 3a9726393..98a89f0dc 100644 --- a/main/channel.c +++ b/main/channel.c @@ -1294,7 +1294,7 @@ void ast_channel_free(struct ast_channel *chan) /* Get rid of each of the data stores on the channel */ while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry))) /* Free the data store */ - ast_channel_datastore_free(datastore); + ast_datastore_free(datastore); /* Lock and unlock the channel just to be sure nobody has it locked still due to a reference that was stored in a datastore. (i.e. app_chanspy) */ @@ -1369,46 +1369,12 @@ void ast_channel_free(struct ast_channel *chan) struct ast_datastore *ast_channel_datastore_alloc(const struct ast_datastore_info *info, const char *uid) { - struct ast_datastore *datastore = NULL; - - /* Make sure we at least have type so we can identify this */ - if (!info) { - return NULL; - } - - /* Allocate memory for datastore and clear it */ - datastore = ast_calloc(1, sizeof(*datastore)); - if (!datastore) { - return NULL; - } - - datastore->info = info; - - datastore->uid = ast_strdup(uid); - - return datastore; + return ast_datastore_alloc(info, uid); } int ast_channel_datastore_free(struct ast_datastore *datastore) { - int res = 0; - - /* Using the destroy function (if present) destroy the data */ - if (datastore->info->destroy != NULL && datastore->data != NULL) { - datastore->info->destroy(datastore->data); - datastore->data = NULL; - } - - /* Free allocated UID memory */ - if (datastore->uid != NULL) { - ast_free((void *) datastore->uid); - datastore->uid = NULL; - } - - /* Finally free memory used by ourselves */ - ast_free(datastore); - - return res; + return ast_datastore_free(datastore); } int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to) @@ -1417,7 +1383,7 @@ int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel * AST_LIST_TRAVERSE(&from->datastores, datastore, entry) { if (datastore->inheritance > 0) { - datastore2 = ast_channel_datastore_alloc(datastore->info, datastore->uid); + datastore2 = ast_datastore_alloc(datastore->info, datastore->uid); if (datastore2) { datastore2->data = datastore->info->duplicate(datastore->data); datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1; @@ -1450,19 +1416,21 @@ struct ast_datastore *ast_channel_datastore_find(struct ast_channel *chan, const return NULL; AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) { - if (datastore->info == info) { - if (uid != NULL && datastore->uid != NULL) { - if (!strcasecmp(uid, datastore->uid)) { - /* Matched by type AND uid */ - break; - } - } else { - /* Matched by type at least */ - break; - } + if (datastore->info != info) { + continue; + } + + if (uid == NULL) { + /* matched by type only */ + break; + } + + if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) { + /* Matched by type AND uid */ + break; } } - AST_LIST_TRAVERSE_SAFE_END + AST_LIST_TRAVERSE_SAFE_END; return datastore; } diff --git a/main/datastore.c b/main/datastore.c new file mode 100644 index 000000000..be5479796 --- /dev/null +++ b/main/datastore.c @@ -0,0 +1,73 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2007 - 2008, Digium, Inc. + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * + * \brief Asterisk datastore objects + */ + +#include "asterisk.h" + +ASTERISK_FILE_VERSION(__FILE__, "$Revision$") + +#include "asterisk/_private.h" + +#include "asterisk/datastore.h" +#include "asterisk/utils.h" + +struct ast_datastore *ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid) +{ + struct ast_datastore *datastore = NULL; + + /* Make sure we at least have type so we can identify this */ + if (!info) { + return NULL; + } + + /* Allocate memory for datastore and clear it */ + datastore = ast_calloc(1, sizeof(*datastore)); + if (!datastore) { + return NULL; + } + + datastore->info = info; + + datastore->uid = ast_strdup(uid); + + return datastore; +} + +int ast_datastore_free(struct ast_datastore *datastore) +{ + int res = 0; + + /* Using the destroy function (if present) destroy the data */ + if (datastore->info->destroy != NULL && datastore->data != NULL) { + datastore->info->destroy(datastore->data); + datastore->data = NULL; + } + + /* Free allocated UID memory */ + if (datastore->uid != NULL) { + ast_free((void *) datastore->uid); + datastore->uid = NULL; + } + + /* Finally free memory used by ourselves */ + ast_free(datastore); + + return res; +} diff --git a/main/manager.c b/main/manager.c index 746da3b86..e038b740c 100644 --- a/main/manager.c +++ b/main/manager.c @@ -172,6 +172,7 @@ struct mansession { struct eventqent *last_ev; /*!< last event processed. */ int writetimeout; /*!< Timeout for ast_carefulwrite() */ int pending_event; /*!< Pending events indicator in case when waiting_thread is NULL */ + AST_LIST_HEAD_NOLOCK(mansession_datastores, ast_datastore) datastores; /*!< Data stores on the session */ AST_LIST_ENTRY(mansession) list; }; @@ -786,6 +787,14 @@ static void ref_event(struct eventqent *e) static void free_session(struct mansession *s) { struct eventqent *eqe = s->last_ev; + struct ast_datastore *datastore; + + /* Get rid of each of the data stores on the session */ + while ((datastore = AST_LIST_REMOVE_HEAD(&s->datastores, entry))) { + /* Free the data store */ + ast_datastore_free(datastore); + } + if (s->f != NULL) fclose(s->f); ast_mutex_destroy(&s->__lock); @@ -3092,18 +3101,21 @@ static void *session_do(void *data) ast_mutex_init(&s->__lock); s->send_events = -1; + /* Hook to the tail of the event queue */ + s->last_ev = grab_last(); + /* these fields duplicate those in the 'ser' structure */ s->fd = ser->fd; s->f = ser->f; s->sin = ser->requestor; + AST_LIST_HEAD_INIT_NOLOCK(&s->datastores); + AST_LIST_LOCK(&sessions); AST_LIST_INSERT_HEAD(&sessions, s, list); ast_atomic_fetchadd_int(&num_sessions, 1); AST_LIST_UNLOCK(&sessions); - /* Hook to the tail of the event queue */ - s->last_ev = grab_last(); - s->f = ser->f; + astman_append(s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */ for (;;) { if ((res = do_message(s)) < 0) @@ -3729,6 +3741,7 @@ static struct ast_str *generic_http_callback(enum output_format format, */ while ((s->managerid = rand() ^ (unsigned long) s) == 0); s->last_ev = grab_last(); + AST_LIST_HEAD_INIT_NOLOCK(&s->datastores); AST_LIST_LOCK(&sessions); AST_LIST_INSERT_HEAD(&sessions, s, list); ast_atomic_fetchadd_int(&num_sessions, 1); @@ -4258,3 +4271,42 @@ int reload_manager(void) { return __init_manager(1); } + +int astman_datastore_add(struct mansession *s, struct ast_datastore *datastore) +{ + AST_LIST_INSERT_HEAD(&s->datastores, datastore, entry); + + return 0; +} + +int astman_datastore_remove(struct mansession *s, struct ast_datastore *datastore) +{ + return AST_LIST_REMOVE(&s->datastores, datastore, entry) ? 0 : -1; +} + +struct ast_datastore *astman_datastore_find(struct mansession *s, const struct ast_datastore_info *info, const char *uid) +{ + struct ast_datastore *datastore = NULL; + + if (info == NULL) + return NULL; + + AST_LIST_TRAVERSE_SAFE_BEGIN(&s->datastores, datastore, entry) { + if (datastore->info != info) { + continue; + } + + if (uid == NULL) { + /* matched by type only */ + break; + } + + if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) { + /* Matched by type AND uid */ + break; + } + } + AST_LIST_TRAVERSE_SAFE_END; + + return datastore; +} diff --git a/main/pbx.c b/main/pbx.c index 9772ca53c..3edea4e05 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -2558,17 +2558,17 @@ int pbx_builtin_raise_exception(struct ast_channel *chan, void *vreason) struct pbx_exception *exception = NULL; if (!ds) { - ds = ast_channel_datastore_alloc(&exception_store_info, NULL); + ds = ast_datastore_alloc(&exception_store_info, NULL); if (!ds) return -1; exception = ast_calloc(1, sizeof(struct pbx_exception)); if (!exception) { - ast_channel_datastore_free(ds); + ast_datastore_free(ds); return -1; } if (ast_string_field_init(exception, 128)) { ast_free(exception); - ast_channel_datastore_free(ds); + ast_datastore_free(ds); return -1; } ds->data = exception; |