[asterisk-commits] russell: branch 1.4 r55758 -
/branches/1.4/apps/app_meetme.c
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Tue Feb 20 18:03:26 MST 2007
Author: russell
Date: Tue Feb 20 19:03:25 2007
New Revision: 55758
URL: http://svn.digium.com/view/asterisk?view=rev&rev=55758
Log:
Improve the reference counting to fix bugs where people report seeing
conferences listed that have no members.
(issue #9073)
Modified:
branches/1.4/apps/app_meetme.c
Modified: branches/1.4/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_meetme.c?view=diff&rev=55758&r1=55757&r2=55758
==============================================================================
--- branches/1.4/apps/app_meetme.c (original)
+++ branches/1.4/apps/app_meetme.c Tue Feb 20 19:03:25 2007
@@ -641,7 +641,7 @@
static struct ast_conference *build_conf(char *confno, char *pin, char *pinadmin, int make, int dynamic, int refcount)
{
struct ast_conference *cnf;
- struct zt_confinfo ztc;
+ struct zt_confinfo ztc = { 0, };
AST_LIST_LOCK(&confs);
@@ -662,8 +662,6 @@
ast_copy_string(cnf->confno, confno, sizeof(cnf->confno));
ast_copy_string(cnf->pin, pin, sizeof(cnf->pin));
ast_copy_string(cnf->pinadmin, pinadmin, sizeof(cnf->pinadmin));
- cnf->refcount = 0;
- cnf->markedusers = 0;
cnf->chan = ast_request("zap", AST_FORMAT_SLINEAR, "pseudo", NULL);
if (cnf->chan) {
ast_set_read_format(cnf->chan, AST_FORMAT_SLINEAR);
@@ -679,9 +677,8 @@
goto cnfout;
}
}
- memset(&ztc, 0, sizeof(ztc));
+
/* Setup a new zap conference */
- ztc.chan = 0;
ztc.confno = -1;
ztc.confmode = ZT_CONF_CONFANN | ZT_CONF_CONFANNMON;
if (ioctl(cnf->fd, ZT_SETCONF, &ztc)) {
@@ -716,7 +713,7 @@
cnfout:
if (cnf)
- cnf->refcount += refcount;
+ ast_atomic_fetchadd_int(&cnf->refcount, refcount);
AST_LIST_UNLOCK(&confs);
@@ -1063,6 +1060,7 @@
conf->recording = MEETME_RECORD_TERMINATE;
AST_LIST_UNLOCK(&confs);
while (1) {
+ usleep(1);
AST_LIST_LOCK(&confs);
if (conf->recording == MEETME_RECORD_OFF)
break;
@@ -1148,6 +1146,22 @@
ast_cond_signal(&sla.cond);
ast_mutex_unlock(&sla.lock);
}
+
+/* Decrement reference counts, as incremented by find_conf() */
+static int dispose_conf(struct ast_conference *conf)
+{
+ int res = 0;
+
+ AST_LIST_LOCK(&confs);
+ if (ast_atomic_dec_and_test(&conf->refcount)) {
+ conf_free(conf);
+ res = 1;
+ }
+ AST_LIST_UNLOCK(&confs);
+
+ return res;
+}
+
static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int confflags, char *optargs[])
{
@@ -1191,15 +1205,8 @@
char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
char *buf = __buf + AST_FRIENDLY_OFFSET;
- if (!(user = ast_calloc(1, sizeof(*user)))) {
- AST_LIST_LOCK(&confs);
- conf->refcount--;
- if (!conf->refcount){
- conf_free(conf);
- }
- AST_LIST_UNLOCK(&confs);
+ if (!(user = ast_calloc(1, sizeof(*user))))
return ret;
- }
/* Possible timeout waiting for marked user */
if ((confflags & CONFFLAG_WAITMARKED) &&
@@ -2059,7 +2066,6 @@
}
conf->users--;
- conf->refcount--;
/* Update table */
snprintf(members, sizeof(members), "%d", conf->users);
ast_update_realtime("meetme", "confno", conf->confno, "members", members, NULL);
@@ -2071,12 +2077,7 @@
/* Change any states */
if (!conf->users)
ast_device_state_changed("meetme:%s", conf->confno);
-
- if (AST_LIST_EMPTY(&conf->userlist)) {
- /* close this one when no more users and no references*/
- if (!conf->refcount)
- conf_free(conf);
- }
+
/* Return the number of seconds the user was in the conf */
snprintf(meetmesecs, sizeof(meetmesecs), "%d", (int) (time(NULL) - user->jointime));
pbx_builtin_setvar_helper(chan, "MEETMESECS", meetmesecs);
@@ -2265,11 +2266,13 @@
AST_STANDARD_APP_ARGS(args, localdata);
- conf = find_conf(chan, args.confno, 0, 0, NULL, 0, 0, NULL);
-
- if (conf)
+ conf = find_conf(chan, args.confno, 0, 0, NULL, 0, 1, NULL);
+
+ if (conf) {
count = conf->users;
- else
+ dispose_conf(conf);
+ conf = NULL;
+ } else
count = 0;
if (!ast_strlen_zero(args.varname)){
@@ -2294,7 +2297,7 @@
char confno[MAX_CONFNUM] = "";
int allowretry = 0;
int retrycnt = 0;
- struct ast_conference *cnf;
+ struct ast_conference *cnf = NULL;
struct ast_flags confflags = {0};
int dynamic = 0;
int empty = 0, empty_no_pin = 0;
@@ -2505,15 +2508,8 @@
ast_log(LOG_WARNING, "Couldn't play invalid pin msg!\n");
break;
}
- if (res < 0) {
- AST_LIST_LOCK(&confs);
- cnf->refcount--;
- if (!cnf->refcount){
- conf_free(cnf);
- }
- AST_LIST_UNLOCK(&confs);
+ if (res < 0)
break;
- }
pin[0] = res;
pin[1] = '\0';
res = -1;
@@ -2525,12 +2521,6 @@
res = -1;
allowretry = 0;
/* see if we need to get rid of the conference */
- AST_LIST_LOCK(&confs);
- cnf->refcount--;
- if (!cnf->refcount) {
- conf_free(cnf);
- }
- AST_LIST_UNLOCK(&confs);
break;
}
@@ -2547,9 +2537,14 @@
res = conf_run(chan, cnf, confflags.flags, optargs);
}
}
+ dispose_conf(cnf);
+ cnf = NULL;
}
} while (allowretry);
-
+
+ if (cnf)
+ dispose_conf(cnf);
+
ast_module_user_remove(u);
return res;
@@ -2612,6 +2607,8 @@
ast_module_user_remove(u);
return 0;
}
+
+ ast_atomic_fetchadd_int(&cnf->refcount, 1);
if (args.user)
user = find_user(cnf, args.user);
@@ -2716,6 +2713,8 @@
AST_LIST_UNLOCK(&confs);
+ dispose_conf(cnf);
+
ast_module_user_remove(u);
return 0;
@@ -3009,8 +3008,11 @@
CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_PASS_DTMF | CONFFLAG_SLA_STATION);
ast_answer(trunk_ref->chan);
conf = build_conf(conf_name, "", "", 0, 0, 1);
- if (conf)
+ if (conf) {
conf_run(trunk_ref->chan, conf, conf_flags.flags, NULL);
+ dispose_conf(conf);
+ conf = NULL;
+ }
trunk_ref->chan = NULL;
if (ast_atomic_dec_and_test((int *) &trunk_ref->trunk->active_stations)) {
strncat(conf_name, "|K", sizeof(conf_name) - strlen(conf_name) - 1);
@@ -3325,8 +3327,11 @@
ast_cond_signal(args->cond);
ast_mutex_unlock(args->cond_lock);
- if (conf)
+ if (conf) {
conf_run(trunk->chan, conf, conf_flags.flags, NULL);
+ dispose_conf(conf);
+ conf = NULL;
+ }
trunk->chan = NULL;
@@ -3431,8 +3436,11 @@
trunk_ref->chan = chan;
ast_answer(chan);
conf = build_conf(conf_name, "", "", 0, 0, 1);
- if (conf)
+ if (conf) {
conf_run(chan, conf, conf_flags.flags, NULL);
+ dispose_conf(conf);
+ conf = NULL;
+ }
trunk_ref->chan = NULL;
res = ast_atomic_fetchadd_int((int *) &trunk_ref->trunk->active_stations, -1);
if (res == 1) {
@@ -3508,6 +3516,8 @@
CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_MARKEDUSER | CONFFLAG_PASS_DTMF);
ast_indicate(chan, AST_CONTROL_RINGING);
conf_run(chan, conf, conf_flags.flags, NULL);
+ dispose_conf(conf);
+ conf = NULL;
trunk->chan = NULL;
pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "SUCCESS");
More information about the asterisk-commits
mailing list