[asterisk-commits] mmichelson: branch mmichelson/queue_refcount r81386 - in /team/mmichelson/que...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Aug 30 12:13:29 CDT 2007


Author: mmichelson
Date: Thu Aug 30 12:13:28 2007
New Revision: 81386

URL: http://svn.digium.com/view/asterisk?view=rev&rev=81386
Log:
Fixed the refcounting for realtime queues.

Here's the "issue" at the moment. The current app_queue procedure makes it so that a realtime queue will be destroyed
the first time that a call is attempted on the queue once it is removed from realtime. This is a bit unnatural and also
means the queue stays in memory longer than its actual life. The reason for this is that realtime queues have no way to
be marked "dead" until we search for them in realtime, and the only way we'll search for them in realtime is a caller attempts
to enter the queue (or if queue show or some other cli or manager command needs to find the queue)


Modified:
    team/mmichelson/queue_refcount/   (props changed)
    team/mmichelson/queue_refcount/apps/app_queue.c
    team/mmichelson/queue_refcount/channels/chan_sip.c
    team/mmichelson/queue_refcount/main/Makefile

Propchange: team/mmichelson/queue_refcount/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Aug 30 12:13:28 2007
@@ -1,1 +1,1 @@
-/branches/1.4:1-81301
+/branches/1.4:1-81358

Modified: team/mmichelson/queue_refcount/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue_refcount/apps/app_queue.c?view=diff&rev=81386&r1=81385&r2=81386
==============================================================================
--- team/mmichelson/queue_refcount/apps/app_queue.c (original)
+++ team/mmichelson/queue_refcount/apps/app_queue.c Thu Aug 30 12:13:28 2007
@@ -321,6 +321,7 @@
 	int penalty;                        /*!< Are we a last resort? */
 	int calls;                          /*!< Number of calls serviced by this member */
 	int dynamic;                        /*!< Are we dynamically added? */
+	int realtime;                       /*!< Is this member realtime? */
 	int status;                         /*!< Status of queue member */
 	int paused;                         /*!< Are we paused (not accepting calls)? */
 	time_t lastcall;                    /*!< When last successful call was hungup */
@@ -465,6 +466,18 @@
 	return !strcasecmp(q->name, q2->name) ? CMP_MATCH : 0;
 }
 
+static inline struct call_queue *queue_ref(struct call_queue *q)
+{
+	ao2_ref(q, 1);
+	return q;
+}
+
+static inline struct call_queue *queue_unref(struct call_queue *q)
+{
+	ao2_ref(q, -1);
+	return q;
+}
+
 
 /*! \brief Insert the 'new' entry after the 'prev' entry of queue 'q' */
 static inline void insert_entry(struct call_queue *q, struct queue_ent *prev, struct queue_ent *new, int *pos)
@@ -604,7 +617,7 @@
 			}
 		}
 		ast_mutex_unlock(&q->lock);
-		ao2_ref(q, -1);
+		queue_unref(q);
 	}
 
 	free(sc);
@@ -742,10 +755,10 @@
 		}
 		ast_mutex_unlock(&q->lock);
 		if (ret) {
-			ao2_ref(q, -1);
+			queue_unref(q);
 			break;
 		}
-		ao2_ref(q, -1);
+		queue_unref(q);
 	}
 
 	return ret;
@@ -964,6 +977,7 @@
 	if (!m) {
 		if ((m = create_queue_member(interface, membername, penalty, paused))) {
 			m->dead = 0;
+			m->realtime = 1;
 			add_to_interfaces(interface);
 			if (prev_m) {
 				prev_m->next = m;
@@ -1044,7 +1058,7 @@
 		if (!q->realtime) {
 			if (q->dead) {
 				ast_mutex_unlock(&q->lock);
-				ao2_ref(q, -1);
+				queue_unref(q);
 				return NULL;
 			} else {
 				ast_mutex_unlock(&q->lock);
@@ -1067,7 +1081,11 @@
 			q->dead = 1;
 			ast_mutex_unlock(&q->lock);
 			ao2_unlink(queues, q);
-			ao2_ref(q, -1);
+			/*In this case, we must unref the queue twice since it was reffed once in load_realtime_queue
+			 * and again locally. Otherwise, there's a memory leak
+			 */
+			queue_unref(q);
+			queue_unref(q);
 		}
 		return NULL;
 	}
@@ -1080,7 +1098,7 @@
 		clear_queue(q);
 		q->realtime = 1;
 		ao2_link(queues, q);
-		ao2_ref(q, 1);
+		queue_ref(q);
 	}
 	init_queue(q);		/* Ensure defaults for all parameters not set explicitly. */
 
@@ -1101,10 +1119,10 @@
 	if (q->strategy == QUEUE_STRATEGY_ROUNDROBIN)
 		rr_dep_warning();
 
-	/* Temporarily set non-dynamic members dead so we can detect deleted ones. 
+	/* Temporarily set realtime members dead so we can detect deleted ones. 
 	 * Also set the membercount correctly for realtime*/
 	for (m = q->members; m; m = m->next, q->membercount++) {
-		if (!m->dynamic)
+		if (m->realtime)
 			m->dead = 1;
 	}
 
@@ -1142,6 +1160,25 @@
 	return q;
 }
 
+static int update_realtime_member_field(struct member *mem, const char *queue_name, const char *field, const char *value)
+{
+	struct ast_variable *var;
+	int ret = -1;
+
+	if(!(var = ast_load_realtime("queue_members", "interface", mem->interface, "queue_name", queue_name, NULL))) 
+		return ret;
+	while (var) {
+		if(!strcmp(var->name, "uniqueid"))
+			break;
+		var = var->next;
+	}
+	if(var && !ast_strlen_zero(var->value)) {
+		if ((ast_update_realtime("queue_members", "uniqueid", var->value, field, value, NULL)) > -1)
+			ret = 0;
+	}
+	return ret;
+}
+
 static void update_realtime_members(struct call_queue *q)
 {
 	struct ast_config *member_config = NULL;
@@ -1158,9 +1195,9 @@
 
 	ast_mutex_lock(&q->lock);
 	
-	/* Temporarily set non-dynamic members dead so we can detect deleted ones.*/ 
+	/* Temporarily set realtime  members dead so we can detect deleted ones.*/ 
 	for (m = q->members; m; m = m->next) {
-		if (!m->dynamic)
+		if (m->realtime)
 			m->dead = 1;
 	}
 
@@ -1481,7 +1518,7 @@
 
 	if (!(q = qe->parent))
 		return;
-	ao2_ref(q, 1);
+	queue_ref(q);
 	ast_mutex_lock(&q->lock);
 
 	prev = NULL;
@@ -1512,7 +1549,7 @@
 		/* It's dead and nobody is in it, so kill it */
 		ao2_unlink(queues, q);
 	}
-	ao2_ref(q, -1);
+	queue_unref(q);
 }
 
 /* Hang up a list of outgoing calls */
@@ -1588,14 +1625,14 @@
 	i = ao2_iterator_init(queues, 0);
 	while ((q = ao2_iterator_next(&i))) {
 		if (q == rq) { /* don't check myself, could deadlock */
-			ao2_ref(q, -1);
+			queue_unref(q);
 			continue;
 		}
 		ast_mutex_lock(&q->lock);
 		if (q->count && q->members) {
 			for (mem = q->members; mem; mem = mem->next) {
 				if (strcmp(mem->interface, member->interface)) {
-					ao2_ref(q, -1);
+					queue_unref(q);
 					continue;
 				}
 
@@ -1603,17 +1640,17 @@
 				if (q->weight > rq->weight) {
 					ast_log(LOG_DEBUG, "Queue '%s' (weight %d, calls %d) is preferred over '%s' (weight %d, calls %d)\n", q->name, q->weight, q->count, rq->name, rq->weight, rq->count);
 					found = 1;
-					ao2_ref(q, -1);
+					queue_unref(q);
 					break;
 				}
 			}
 		}
 		ast_mutex_unlock(&q->lock);
 		if (found) {
-			ao2_ref(q, -1);
+			queue_unref(q);
 			break;
 		}
-		ao2_ref(q, -1);
+		queue_unref(q);
 	}
 	return found;
 }
@@ -2894,7 +2931,7 @@
 		res = RES_EXISTS;
 	}
 	ast_mutex_unlock(&q->lock);
-	ao2_ref(q, -1);
+	queue_unref(q);
 
 	if (res == RES_OKAY)
 		remove_from_interfaces(interface);
@@ -2980,6 +3017,9 @@
 				if (queue_persistent_members)
 					dump_queue_members(q);
 
+				if(mem->realtime)
+					update_realtime_member_field(mem, queuename, "paused", paused ? "1" : "0");
+
 				ast_queue_log(q->name, "NONE", mem->membername, (paused ? "PAUSE" : "UNPAUSE"), "%s", "");
 
 				manager_event(EVENT_FLAG_AGENT, "QueueMemberPaused",
@@ -2991,7 +3031,7 @@
 			}
 		}
 		ast_mutex_unlock(&q->lock);
-		ao2_ref(q, -1);
+		queue_unref(q);
 	}
 
 	return found ? RESULT_SUCCESS : RESULT_FAILURE;
@@ -3645,7 +3685,7 @@
 	if (q) {
 		count = q->membercount;
 		ast_mutex_unlock(&q->lock);
-		ao2_ref(q, -1);
+		queue_unref(q);
 	} else
 		ast_log(LOG_WARNING, "queue %s was not found\n", data);
 
@@ -3678,7 +3718,7 @@
 	if (q) {
 		count = q->count;
 		ast_mutex_unlock(&q->lock);
-		ao2_ref(q, -1);
+		queue_unref(q);
 	} else
 		ast_log(LOG_WARNING, "queue %s was not found\n", data);
 
@@ -3725,7 +3765,7 @@
 			}
 		}
 		ast_mutex_unlock(&q->lock);
-		ao2_ref(q, -1);
+		queue_unref(q);
 	} else
 		ast_log(LOG_WARNING, "queue %s was not found\n", data);
 
@@ -3803,7 +3843,7 @@
 	i = ao2_iterator_init(queues, 0);
 	while((q = ao2_iterator_next(&i))) {
 		q->dead = 1;
-		ao2_ref(q, -1);
+		queue_unref(q);
 	}
 
 	/* Chug through config file */
@@ -3923,10 +3963,10 @@
 
 				if (new) {
 					ao2_link(queues, q);
-					ao2_ref(q, 1);
+					queue_ref(q);
 				} else
 					ast_mutex_unlock(&q->lock);
-				ao2_ref(q, -1);
+				queue_unref(q);
 			}
 		}
 	}
@@ -3944,7 +3984,7 @@
 			}
 			ast_mutex_unlock(&q->lock);
 		}
-		ao2_ref(q, -1);
+		queue_unref(q);
 	}
 	return 1;
 }
@@ -4066,13 +4106,11 @@
 	ao2_unlock(queues);
 
 	if(queue_show) {
-		struct call_queue tmpq;
-		ast_copy_string(tmpq.name, argv[2], sizeof(tmpq.name));
 		if(!(q = load_realtime_queue(argv[2])))
 			ast_cli(fd, "No such queue: %s.%s", argv[2], term);
 		else {
 			show(q, fd, argv, s, term);
-			ao2_ref(q, -1);
+			queue_unref(q);
 		}
 	} else {
 		i = ao2_iterator_init(queues, 0);
@@ -4080,7 +4118,7 @@
 			ast_mutex_lock(&q->lock);
 			show(q, fd, argv, s, term);
 			ast_mutex_unlock(&q->lock);
-			ao2_ref(q, -1);
+			queue_unref(q);
 		}
 	}
 	return RESULT_SUCCESS;
@@ -4103,10 +4141,10 @@
 	while((q = ao2_iterator_next(&i))) {
 		if (!strncasecmp(word, q->name, wordlen) && ++which > state) {
 			ret = ast_strdup(q->name);
-			ao2_ref(q, -1);
+			queue_unref(q);
 			break;
 		}
-		ao2_ref(q, -1);
+		queue_unref(q);
 	}
 
 	return ret;
@@ -4210,7 +4248,7 @@
 			}
 		}
 		ast_mutex_unlock(&q->lock);
-		ao2_ref(q, -1);
+		queue_unref(q);
 	}
 
 	astman_append(s,
@@ -4472,12 +4510,12 @@
 		for (m = q->members ; m ; m = m->next) {
 			if (++which > state) {
 				ast_mutex_unlock(&q->lock);
-				ao2_ref(q, -1);
+				queue_unref(q);
 				return ast_strdup(m->interface);
 			}
 		}
 		ast_mutex_unlock(&q->lock);
-		ao2_ref(q, -1);
+		queue_unref(q);
 	}
 
 	return NULL;

Modified: team/mmichelson/queue_refcount/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue_refcount/channels/chan_sip.c?view=diff&rev=81386&r1=81385&r2=81386
==============================================================================
--- team/mmichelson/queue_refcount/channels/chan_sip.c (original)
+++ team/mmichelson/queue_refcount/channels/chan_sip.c Thu Aug 30 12:13:28 2007
@@ -15318,15 +15318,12 @@
 								ast_mutex_lock(&sip->lock);
 							}
 							if (sip->owner) {
-								if (!(ast_rtp_get_bridged(sip->rtp))) {
-									ast_log(LOG_NOTICE,
-										"Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
-										sip->owner->name,
-										(long) (t - sip->lastrtprx));
-									/* Issue a softhangup */
-									ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV);
-								} else
-									ast_log(LOG_NOTICE, "'%s' will not be disconnected in %ld seconds because it is directly bridged to another RTP stream\n", sip->owner->name, (long) (t - sip->lastrtprx));
+								ast_log(LOG_NOTICE,
+									"Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
+									sip->owner->name,
+									(long) (t - sip->lastrtprx));
+								/* Issue a softhangup */
+								ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV);
 								ast_channel_unlock(sip->owner);
 								/* forget the timeouts for this call, since a hangup
 								   has already been requested and we don't want to

Modified: team/mmichelson/queue_refcount/main/Makefile
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue_refcount/main/Makefile?view=diff&rev=81386&r1=81385&r2=81386
==============================================================================
--- team/mmichelson/queue_refcount/main/Makefile (original)
+++ team/mmichelson/queue_refcount/main/Makefile Thu Aug 30 12:13:28 2007
@@ -135,7 +135,11 @@
 	@rm -f $(ASTTOPDIR)/include/asterisk/build.h.tmp
 	@$(CC) -c -o buildinfo.o $(ASTCFLAGS) buildinfo.c
 	$(ECHO_PREFIX) echo "   [LD] $^ -> $@"
+ifneq ($(findstring chan_h323,$(MENUSELECT_CHANNELS)),)
+	$(CMD_PREFIX) $(CC) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(ASTLDFLAGS) $^ buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS)
+else
 	$(CMD_PREFIX) $(CXX) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(ASTLDFLAGS) $(H323LDFLAGS) $^ buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS) $(H323LDLIBS)
+endif
 	@$(ASTTOPDIR)/build_tools/strip_nonapi $@
 
 clean::




More information about the asterisk-commits mailing list