From a4c9b2cc37df53b43628de44a47106e360fa524e Mon Sep 17 00:00:00 2001 From: markster Date: Mon, 30 Dec 2002 13:09:27 +0000 Subject: Version 0.3.0 from FTP git-svn-id: http://svn.digium.com/svn/asterisk/trunk@575 f38db490-d61c-443f-a65b-d21fe96a405b --- autoservice.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100755 autoservice.c diff --git a/autoservice.c b/autoservice.c new file mode 100755 index 000000000..5f15c244c --- /dev/null +++ b/autoservice.c @@ -0,0 +1,152 @@ +/* + * Asterisk -- A telephony toolkit for Linux. + * + * Automatic channel service routines + * + * Copyright (C) 1999, Mark Spencer + * + * Mark Spencer + * + * This program is free software, distributed under the terms of + * the GNU General Public License + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include /* For PI */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_AUTOMONS 256 + +static pthread_mutex_t autolock = AST_MUTEX_INITIALIZER; + +struct asent { + struct ast_channel *chan; + struct asent *next; +}; + +static struct asent *aslist = NULL; +static pthread_t asthread = -1; + +static void *autoservice_run(void *ign) +{ + struct ast_channel *mons[MAX_AUTOMONS]; + int x; + int ms; + struct ast_channel *chan; + struct asent *as; + struct ast_frame *f; + for(;;) { + x = 0; + ast_pthread_mutex_lock(&autolock); + as = aslist; + while(as) { + if (!as->chan->_softhangup) { + if (x < MAX_AUTOMONS) + mons[x++] = as->chan; + else + ast_log(LOG_WARNING, "Exceeded maximum number of automatic monitoring events. Fix autoservice.c\n"); + } + as = as->next; + } + ast_pthread_mutex_unlock(&autolock); + +/* if (!aslist) + break; */ + ms = 500; + chan = ast_waitfor_n(mons, x, &ms); + if (chan) { + /* Read and ignore anything that occurs */ + f = ast_read(chan); + if (f) + ast_frfree(f); + } + } + asthread = -1; + return NULL; +} + +int ast_autoservice_start(struct ast_channel *chan) +{ + int res = -1; + struct asent *as; + int needstart; + ast_pthread_mutex_lock(&autolock); + needstart = (asthread == -1) ? 1 : 0 /* aslist ? 0 : 1 */; + as = aslist; + while(as) { + if (as->chan == chan) + break; + as = as->next; + } + if (!as) { + as = malloc(sizeof(struct asent)); + if (as) { + memset(as, 0, sizeof(struct asent)); + as->chan = chan; + as->next = aslist; + aslist = as; + res = 0; + if (needstart) { + if (pthread_create(&asthread, NULL, autoservice_run, NULL)) { + ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n"); + free(aslist); + aslist = NULL; + res = -1; + } else + pthread_kill(asthread, SIGURG); + } + } + } + ast_pthread_mutex_unlock(&autolock); + return res; +} + +int ast_autoservice_stop(struct ast_channel *chan) +{ + int res = -1; + struct asent *as, *prev; + ast_pthread_mutex_lock(&autolock); + as = aslist; + prev = NULL; + while(as) { + if (as->chan == chan) + break; + prev = as; + as = as->next; + } + if (as) { + if (prev) + prev->next = as->next; + else + aslist = as->next; + free(as); + if (!chan->_softhangup) + res = 0; + } + if (asthread != -1) + pthread_kill(asthread, SIGURG); + ast_pthread_mutex_unlock(&autolock); + /* Wait for it to un-block */ + while(chan->blocking) + usleep(1000); + return res; +} -- cgit v1.2.3