Index: apps/app_meetme.c
===================================================================
--- apps/app_meetme.c	(revision 11164)
+++ apps/app_meetme.c	(working copy)
@@ -150,6 +150,7 @@
 	int recording;				/* recording status */
 	int isdynamic;				/* Created on the fly? */
 	int locked;				/* Is the conference locked? */
+	int refcount;				/* ref count of usage */
 	pthread_t recordthread;			/* thread for recording */
 	pthread_attr_t attr;			/* thread attribute */
 	const char *recordingfilename;		/* Filename to record the Conference into */
@@ -452,7 +453,7 @@
 		ast_autoservice_stop(chan);
 }
 
-static struct ast_conference *build_conf(char *confno, char *pin, char *pinadmin, int make, int dynamic)
+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;
@@ -473,6 +474,7 @@
 			ast_copy_string(cnf->pin, pin, sizeof(cnf->pin));
 			ast_copy_string(cnf->pinadmin, pinadmin, sizeof(cnf->pinadmin));
 			cnf->markedusers = 0;
+			cnf->refcount = 0;
 			cnf->chan = ast_request("zap", AST_FORMAT_SLINEAR, "pseudo", NULL);
 			if (cnf->chan) {
 				ast_set_read_format(cnf->chan, AST_FORMAT_SLINEAR);
@@ -528,6 +530,9 @@
 		} 
 	}
  cnfout:
+	if (cnf){ 
+		cnf->refcount += refcount;
+	}
 	AST_LIST_UNLOCK(&confs);
 	return cnf;
 }
@@ -783,7 +788,7 @@
 static int conf_free(struct ast_conference *conf)
 {
 	int x;
-	
+
 	AST_LIST_REMOVE(&confs, conf, list);
 
 	if (conf->recording == MEETME_RECORD_ACTIVE) {
@@ -857,6 +862,12 @@
 	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);
 		return ret;
 	}
 
@@ -1665,11 +1676,14 @@
 		          "<no name>", hr, min, sec);
 
 		conf->users--;
+		conf->refcount--;
 		if (confflags & CONFFLAG_MARKEDUSER) 
 			conf->markedusers--;
 		if (!conf->users) {
-			/* No more users -- close this one out */
-			conf_free(conf);
+			/* close this one when no more users and no references*/
+			if (!conf->refcount){
+				conf_free(conf);
+			}
 		} else {
 			/* Remove the user struct */ 
 			if (user == conf->firstuser) {
@@ -1709,7 +1723,7 @@
 	return ret;
 }
 
-static struct ast_conference *find_conf(struct ast_channel *chan, char *confno, int make, int dynamic, char *dynamic_pin)
+static struct ast_conference *find_conf(struct ast_channel *chan, char *confno, int make, int dynamic, char *dynamic_pin, int refcount)
 {
 	struct ast_config *cfg;
 	struct ast_variable *var;
@@ -1727,6 +1741,9 @@
 		if (!strcmp(confno, cnf->confno)) 
 			break;
 	}
+	if (cnf){
+		cnf->refcount += refcount;
+	}
 	AST_LIST_UNLOCK(&confs);
 
 	if (!cnf) {
@@ -1739,9 +1756,9 @@
 					if (ast_app_getdata(chan, "conf-getpin", dynamic_pin, AST_MAX_EXTENSION - 1, 0) < 0)
 						return NULL;
 				}
-				cnf = build_conf(confno, dynamic_pin, "", make, dynamic);
+				cnf = build_conf(confno, dynamic_pin, "", make, dynamic, refcount);
 			} else {
-				cnf = build_conf(confno, "", "", make, dynamic);
+				cnf = build_conf(confno, "", "", make, dynamic, refcount);
 			}
 		} else {
 			/* Check the config */
@@ -1763,14 +1780,14 @@
 					/* Bingo it's a valid conference */
 					if (args.pin) {
 						if (args.pinadmin)
-							cnf = build_conf(args.confno, args.pin, args.pinadmin, make, dynamic);
+							cnf = build_conf(args.confno, args.pin, args.pinadmin, make, dynamic, refcount);
 						else
-							cnf = build_conf(args.confno, args.pin, "", make, dynamic);
+							cnf = build_conf(args.confno, args.pin, "", make, dynamic, refcount);
 					} else {
 						if (args.pinadmin)
-							cnf = build_conf(args.confno, "", args.pinadmin, make, dynamic);
+							cnf = build_conf(args.confno, "", args.pinadmin, make, dynamic, refcount);
 						else
-							cnf = build_conf(args.confno, "", "", make, dynamic);
+							cnf = build_conf(args.confno, "", "", make, dynamic, refcount);
 					}
 					break;
 				}
@@ -1819,7 +1836,7 @@
 
 	AST_STANDARD_APP_ARGS(args, localdata);
 	
-	conf = find_conf(chan, args.confno, 0, 0, NULL);
+	conf = find_conf(chan, args.confno, 0, 0, NULL, 0);
 	if (conf)
 		count = conf->users;
 	else
@@ -2005,7 +2022,7 @@
 		}
 		if (!ast_strlen_zero(confno)) {
 			/* Check the validity of the conference */
-			cnf = find_conf(chan, confno, 1, dynamic, the_pin);
+			cnf = find_conf(chan, confno, 1, dynamic, the_pin, 1);
 			if (!cnf) {
 				res = ast_streamfile(chan, "conf-invalid", chan->language);
 				if (!res)
@@ -2046,8 +2063,15 @@
 								res = ast_streamfile(chan, "conf-invalidpin", chan->language);
 								if (!res)
 									ast_waitstream(chan, AST_DIGIT_ANY);
-								if (res < 0)
+								if (res < 0){
+									AST_LIST_LOCK(&confs);
+									cnf->refcount--;
+									if (!cnf->refcount){
+										conf_free(cnf);
+									}
+									AST_LIST_UNLOCK(&confs);
 									break;
+								}
 								pin[0] = res;
 								pin[1] = '\0';
 								res = -1;
@@ -2060,8 +2084,9 @@
 							allowretry = 0;
 							/* see if we need to get rid of the conference */
 							AST_LIST_LOCK(&confs);
-							if (!cnf->users) {
-								conf_free(cnf);	
+							cnf->refcount--;
+							if (!cnf->refcount){
+								conf_free(cnf);
 							}
 							AST_LIST_UNLOCK(&confs);
 							break;
