[asterisk-commits] russell: branch russell/res_monkeys r81289 - in /team/russell/res_monkeys: ap...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Aug 28 15:33:48 CDT 2007
Author: russell
Date: Tue Aug 28 15:33:47 2007
New Revision: 81289
URL: http://svn.digium.com/view/asterisk?view=rev&rev=81289
Log:
Change func_announce to use a channel attached thread. To do this, I updated
channel attached threads to be both stopped automatically on channel destruction
as well as able to be stopped early. In this case, it is exposed to the dialplan
using a function.
Modified:
team/russell/res_monkeys/apps/app_monkeys.c
team/russell/res_monkeys/funcs/func_announce.c
team/russell/res_monkeys/include/asterisk/channel.h
team/russell/res_monkeys/main/channel.c
Modified: team/russell/res_monkeys/apps/app_monkeys.c
URL: http://svn.digium.com/view/asterisk/team/russell/res_monkeys/apps/app_monkeys.c?view=diff&rev=81289&r1=81288&r2=81289
==============================================================================
--- team/russell/res_monkeys/apps/app_monkeys.c (original)
+++ team/russell/res_monkeys/apps/app_monkeys.c Tue Aug 28 15:33:47 2007
@@ -117,7 +117,7 @@
u = ast_module_user_add(chan);
- if (ast_chan_thread_create(chan, monkey_thread))
+ if (ast_chan_thread_create(chan, NULL, monkey_thread, NULL, NULL))
res = -1;
ast_module_user_remove(u);
Modified: team/russell/res_monkeys/funcs/func_announce.c
URL: http://svn.digium.com/view/asterisk/team/russell/res_monkeys/funcs/func_announce.c?view=diff&rev=81289&r1=81288&r2=81289
==============================================================================
--- team/russell/res_monkeys/funcs/func_announce.c (original)
+++ team/russell/res_monkeys/funcs/func_announce.c Tue Aug 28 15:33:47 2007
@@ -38,48 +38,50 @@
#include "asterisk/linkedlists.h"
#include "asterisk/audiohook.h"
-static int unique_id;
-
struct announce_data {
struct timeval begin;
int id;
};
-static void announce_ds_destroy(void *arg)
+static void announce_data_destroy(void *data)
{
- struct announce_data *announce = arg;
+ struct announce_data *announce = data;
ast_free(announce);
}
-static const struct ast_datastore_info announce_datastore = {
- .type = "func_announce",
- .destroy = announce_ds_destroy,
-};
+static void *announce_thread(void *data)
+{
+ struct ast_chan_thread_args *thread_args = data;
+ struct announce_data *announce = thread_args->data;
+
+ while (!thread_args->stop_thread) {
+ ast_mutex_lock(&thread_args->lock);
+ if (thread_args->stop_thread) {
+ ast_mutex_unlock(&thread_args->lock);
+ break;
+ }
+ ast_cond_wait(&thread_args->cond, &thread_args->lock);
+ ast_mutex_unlock(&thread_args->lock);
+ }
+
+ return announce;
+}
static int start_announce_read(struct ast_channel *chan, const char *cmd,
char *data, char *buf, size_t len)
{
- struct ast_datastore *datastore;
struct announce_data *announce;
if (!(announce = ast_calloc(1, sizeof(*announce))))
return -1;
- announce->id = ast_atomic_fetchadd_int(&unique_id, +1);
announce->begin = ast_tvnow();
-
+
+ ast_chan_thread_create(chan, &announce->id, announce_thread,
+ announce, announce_data_destroy);
+
snprintf(buf, len, "%d", announce->id);
-
- if (!(datastore = ast_channel_datastore_alloc(&announce_datastore, buf))) {
- ast_free(announce);
- buf[0] = '\0';
- return -1;
- }
-
- ast_channel_lock(chan);
- ast_channel_datastore_add(chan, datastore);
- ast_channel_unlock(chan);
return 0;
}
@@ -87,24 +89,24 @@
static int stop_announce_read(struct ast_channel *chan, const char *cmd,
char *data, char *buf, size_t len)
{
- struct ast_datastore *datastore;
struct announce_data *announce;
+ int id;
- if (!(datastore = ast_channel_datastore_find(chan, &announce_datastore, data))) {
- ast_log(LOG_WARNING, "Periodic Announcement with ID '%s' not found for channel '%s'\n",
- data, chan->name);
+ if (sscanf(data, "%d", &id) != 1) {
+ ast_log(LOG_WARNING, "STOP_ANNOUNCE given invalid argument: '%s'\n", data);
return -1;
}
- ast_channel_lock(chan);
- ast_channel_datastore_remove(chan, datastore);
- ast_channel_unlock(chan);
+ announce = ast_chan_thread_stop(chan, id);
- announce = datastore->data;
+ if (!announce) {
+ ast_log(LOG_ERROR, "No Periodic announcement found for ID '%d'\n", id);
+ return -1;
+ }
snprintf(buf, len, "%d", ast_tvdiff_ms(ast_tvnow(), announce->begin));
- ast_channel_datastore_free(datastore);
+ announce_data_destroy(announce);
return 0;
}
Modified: team/russell/res_monkeys/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/team/russell/res_monkeys/include/asterisk/channel.h?view=diff&rev=81289&r1=81288&r2=81289
==============================================================================
--- team/russell/res_monkeys/include/asterisk/channel.h (original)
+++ team/russell/res_monkeys/include/asterisk/channel.h Tue Aug 28 15:33:47 2007
@@ -1466,13 +1466,19 @@
struct ast_chan_thread_args {
struct ast_channel *chan;
+ int unique_id;
pthread_t thread_id;
+ void *data;
+ void (*data_destructor)(void *);
ast_mutex_t lock;
ast_cond_t cond;
unsigned int stop_thread:1;
};
-int ast_chan_thread_create(struct ast_channel *chan, void *(*start_func)(void *));
+int ast_chan_thread_create(struct ast_channel *chan, int *id, void *(*start_func)(void *),
+ void *data, void (*data_destructor)(void *));
+
+void *ast_chan_thread_stop(struct ast_channel *chan, int id);
/*!
\brief return an english explanation of the code returned thru __ast_request_and_dial's 'outstate' argument
Modified: team/russell/res_monkeys/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/russell/res_monkeys/main/channel.c?view=diff&rev=81289&r1=81288&r2=81289
==============================================================================
--- team/russell/res_monkeys/main/channel.c (original)
+++ team/russell/res_monkeys/main/channel.c Tue Aug 28 15:33:47 2007
@@ -4732,3 +4732,96 @@
snprintf(buf, sizeof(buf), "%d", num);
return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
}
+
+static void chan_thread_destroy(void *data);
+const struct ast_datastore_info chanthread_datastore_info = {
+ .type = "CHANTHREAD",
+ .destroy = chan_thread_destroy,
+};
+
+static void *destroy_chan_thread_args(struct ast_chan_thread_args *thread_args)
+{
+ void *ret = NULL;
+
+ if (thread_args->thread_id != AST_PTHREADT_NULL) {
+ ast_mutex_lock(&thread_args->lock);
+ thread_args->stop_thread = 1;
+ ast_cond_signal(&thread_args->cond);
+ ast_mutex_unlock(&thread_args->lock);
+ pthread_join(thread_args->thread_id, &ret);
+ }
+
+ ast_mutex_destroy(&thread_args->lock);
+ ast_cond_destroy(&thread_args->cond);
+
+ if (thread_args->data && thread_args->data_destructor) {
+ thread_args->data_destructor(thread_args->data);
+ thread_args->data = NULL;
+ }
+
+ ast_free(thread_args);
+
+ return ret;
+}
+
+void *ast_chan_thread_stop(struct ast_channel *chan, int id)
+{
+ struct ast_datastore *datastore;
+ struct ast_chan_thread_args *thread_args;
+ char id_str[32];
+
+ snprintf(id_str, sizeof(id_str), "%d", id);
+
+ ast_channel_lock(chan);
+ datastore = ast_channel_datastore_find(chan, &chanthread_datastore_info, id_str);
+ thread_args = datastore->data;
+ datastore->data = NULL;
+ ast_channel_unlock(chan);
+
+ return destroy_chan_thread_args(thread_args);
+}
+
+static void chan_thread_destroy(void *data)
+{
+ struct ast_chan_thread_args *thread_args = data;
+
+ destroy_chan_thread_args(thread_args);
+}
+
+static int chan_thread_id;
+
+int ast_chan_thread_create(struct ast_channel *chan, int *id, void *(*start_func)(void *),
+ void *data, void (*data_destructor)(void *))
+{
+ struct ast_datastore *datastore;
+ struct ast_chan_thread_args *thread_args;
+ int res;
+ char buf[32];
+
+ if (!(thread_args = ast_calloc(1, sizeof(*thread_args))))
+ return -1;
+
+ thread_args->chan = chan;
+ thread_args->data = data;
+ thread_args->data_destructor = data_destructor;
+ ast_mutex_init(&thread_args->lock);
+ ast_cond_init(&thread_args->cond, NULL);
+ thread_args->thread_id = AST_PTHREADT_NULL;
+ thread_args->unique_id = ast_atomic_fetchadd_int(&chan_thread_id, +1);
+ if (id)
+ *id = thread_args->unique_id;
+
+ snprintf(buf, sizeof(buf), "%d", thread_args->unique_id);
+
+ if (!(datastore = ast_channel_datastore_alloc(&chanthread_datastore_info, buf))) {
+ ast_free(thread_args);
+ return -1;
+ }
+
+ ast_channel_lock(chan);
+ ast_channel_datastore_add(chan, datastore);
+ res = ast_pthread_create_background(&thread_args->thread_id, NULL, start_func, thread_args);
+ ast_channel_unlock(chan);
+
+ return res;
+}
More information about the asterisk-commits
mailing list