[asterisk-commits] russell: branch russell/sla_updates r54437 - in /team/russell/sla_updates: ap...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Wed Feb 14 11:16:19 MST 2007


Author: russell
Date: Wed Feb 14 12:16:18 2007
New Revision: 54437

URL: http://svn.digium.com/view/asterisk?view=rev&rev=54437
Log:
Re-work the SLA thread to improve various things ...

- When a dial state changes, don't require a complete processing loop iteration
  to acknowlege each one, meanwhile blocking the dial threads.  Instead,  when a
  dial state changes, just queue an event on the SLA event queue that says that
  the state of a dial changed.

- Break the SLA thread into various functions based on which type of event the
  code is processing.  This makes the code more readible, but also, ensures
  that no processing is done that doesn't need to be.

Modified:
    team/russell/sla_updates/apps/app_meetme.c
    team/russell/sla_updates/doc/sla.txt

Modified: team/russell/sla_updates/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/russell/sla_updates/apps/app_meetme.c?view=diff&rev=54437&r1=54436&r2=54437
==============================================================================
--- team/russell/sla_updates/apps/app_meetme.c (original)
+++ team/russell/sla_updates/apps/app_meetme.c Wed Feb 14 12:16:18 2007
@@ -408,9 +408,16 @@
 
 static const char sla_registrar[] = "SLA";
 
+/*! \brief Event types that can be queued up for the SLA thread */
 enum sla_event_type {
+	/*! A station has put the call on hold */
 	SLA_EVENT_HOLD,
-	SLA_EVENT_UNHOLD
+	/*! A station has taken the call off of hold */
+	SLA_EVENT_UNHOLD,
+	/*! The state of a dial has changed */
+	SLA_EVENT_DIAL_STATE,
+	/*! The state of a ringing trunk has changed */
+	SLA_EVENT_RINGING_TRUNK,
 };
 
 struct sla_event {
@@ -418,6 +425,14 @@
 	struct sla_station *station;
 	struct sla_trunk_ref *trunk_ref;
 	AST_LIST_ENTRY(sla_event) entry;
+};
+
+/*! \brief A station that failed to be dialed 
+ * \note Only used by the SLA thread. */
+struct sla_failed_station {
+	struct sla_station *station;
+	struct timeval last_try;
+	AST_LIST_ENTRY(sla_failed_station) entry;
 };
 
 /*!
@@ -429,6 +444,8 @@
 	ast_cond_t cond;
 	ast_mutex_t lock;
 	AST_LIST_HEAD_NOLOCK(, sla_trunk_ref) ringing_trunks;
+	AST_LIST_HEAD_NOLOCK(, sla_station_ref) ringing_stations;
+	AST_LIST_HEAD_NOLOCK(, sla_failed_station) failed_stations;
 	AST_LIST_HEAD_NOLOCK(, sla_event) event_q;
 	unsigned int stop:1;
 } sla = {
@@ -1105,10 +1122,33 @@
 	}
 }
 
-static void sla_queue_event(enum sla_event_type type, const struct ast_channel *chan,
+static void sla_queue_event_full(enum sla_event_type type, 
+	struct sla_trunk_ref *trunk_ref, struct sla_station *station)
+{
+	struct sla_event *event;
+
+	if (!(event = ast_calloc(1, sizeof(*event))))
+		return;
+
+	event->type = type;
+	event->trunk_ref = trunk_ref;
+	event->station = station;
+
+	ast_mutex_lock(&sla.lock);
+	AST_LIST_INSERT_TAIL(&sla.event_q, event, entry);
+	ast_cond_signal(&sla.cond);
+	ast_mutex_unlock(&sla.lock);
+}
+
+static void sla_queue_event(enum sla_event_type type)
+{
+	sla_queue_event_full(type, NULL, NULL);
+}
+
+/*! \brief Queue a SLA event from the conference */
+static void sla_queue_event_conf(enum sla_event_type type, const struct ast_channel *chan,
 	struct ast_conference *conf)
 {
-	struct sla_event *event;
 	struct sla_station *station;
 	struct sla_trunk_ref *trunk_ref = NULL;
 	char *trunk_name;
@@ -1136,17 +1176,7 @@
 		return;
 	}
 
-	if (!(event = ast_calloc(1, sizeof(*event))))
-		return;
-
-	event->type = type;
-	event->trunk_ref = trunk_ref;
-	event->station = station;
-
-	ast_mutex_lock(&sla.lock);
-	AST_LIST_INSERT_TAIL(&sla.event_q, event, entry);
-	ast_cond_signal(&sla.cond);
-	ast_mutex_unlock(&sla.lock);
+	sla_queue_event_full(type, trunk_ref, station);
 }
 
 static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int confflags, char *optargs[])
@@ -1923,12 +1953,10 @@
 				} else if ((confflags & CONFFLAG_SLA_STATION) && f->frametype == AST_FRAME_CONTROL) {
 					switch (f->subclass) {
 					case AST_CONTROL_HOLD:
-						ast_log(LOG_DEBUG, "Got a HOLD frame!\n");
-						sla_queue_event(SLA_EVENT_HOLD, chan, conf);
+						sla_queue_event_conf(SLA_EVENT_HOLD, chan, conf);
 						break;
 					case AST_CONTROL_UNHOLD:
-						ast_log(LOG_DEBUG, "Got a UNHOLD frame!\n");
-						sla_queue_event(SLA_EVENT_UNHOLD, chan, conf);
+						sla_queue_event_conf(SLA_EVENT_UNHOLD, chan, conf);
 					default:
 						break;
 					}
@@ -3027,217 +3055,247 @@
 
 static void sla_dial_state_callback(struct ast_dial *dial)
 {
+	sla_queue_event(SLA_EVENT_DIAL_STATE);
+}
+
+static void sla_handle_dial_state_event(void)
+{
+	struct sla_station_ref *station_ref;
+
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, station_ref, entry) {
+		struct sla_trunk_ref *s_trunk_ref, *trunk_ref;
+		struct run_station_args args;
+		enum ast_dial_result dial_res;
+		pthread_attr_t attr;
+		pthread_t dont_care;
+		ast_mutex_t cond_lock;
+		ast_cond_t cond;
+
+		switch ((dial_res = ast_dial_state(station_ref->station->dial))) {
+		case AST_DIAL_RESULT_HANGUP:
+		case AST_DIAL_RESULT_INVALID:
+		case AST_DIAL_RESULT_FAILED:
+		case AST_DIAL_RESULT_TIMEOUT:
+		case AST_DIAL_RESULT_UNANSWERED:
+			AST_LIST_REMOVE_CURRENT(&sla.ringing_stations, entry);
+			ast_dial_join(station_ref->station->dial);
+			ast_dial_destroy(station_ref->station->dial);
+			station_ref->station->dial = NULL;
+			free(station_ref);
+			break;
+		case AST_DIAL_RESULT_ANSWERED:
+			AST_LIST_REMOVE_CURRENT(&sla.ringing_stations, entry);
+			/* Find the appropriate trunk to answer. */
+			AST_LIST_TRAVERSE(&station_ref->station->trunks, s_trunk_ref, entry) {
+				ast_mutex_lock(&sla.lock);
+				AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, trunk_ref, entry) {
+					if (s_trunk_ref->trunk == trunk_ref->trunk) {
+						AST_LIST_REMOVE_CURRENT(&sla.ringing_trunks, entry);
+						break;
+					}
+				}
+				AST_LIST_TRAVERSE_SAFE_END
+				ast_mutex_unlock(&sla.lock);
+				if (trunk_ref)
+					break;
+			}
+			if (!trunk_ref) {
+				ast_log(LOG_DEBUG, "Found no ringing trunk for station '%s' to answer!\n",
+					station_ref->station->name);
+				break;
+			}
+			s_trunk_ref->chan = ast_dial_answered(station_ref->station->dial);
+			ast_answer(trunk_ref->trunk->chan);
+			change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, 0);
+			args.trunk_ref = s_trunk_ref;
+			args.station = station_ref->station;
+			args.cond = &cond;
+			args.cond_lock = &cond_lock;
+			free(trunk_ref);
+			free(station_ref);
+			ast_mutex_init(&cond_lock);
+			ast_cond_init(&cond, NULL);
+			pthread_attr_init(&attr);
+			pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+			ast_mutex_lock(&cond_lock);
+			ast_pthread_create_background(&dont_care, &attr, run_station, &args);
+			ast_cond_wait(&cond, &cond_lock);
+			ast_mutex_unlock(&cond_lock);
+			ast_mutex_destroy(&cond_lock);
+			ast_cond_destroy(&cond);
+			pthread_attr_destroy(&attr);
+			break;
+		case AST_DIAL_RESULT_TRYING:
+		case AST_DIAL_RESULT_RINGING:
+		case AST_DIAL_RESULT_PROGRESS:
+		case AST_DIAL_RESULT_PROCEEDING:
+			break;
+		}
+		if (dial_res == AST_DIAL_RESULT_ANSWERED) {
+			/* Queue up reprocessing ringing trunks, and then ringing stations again */
+			sla_queue_event(SLA_EVENT_RINGING_TRUNK);
+			sla_queue_event(SLA_EVENT_DIAL_STATE);
+			break;
+		}
+	}
+	AST_LIST_TRAVERSE_SAFE_END
+}
+
+static void sla_handle_ringing_trunk_event(void)
+{
+	struct sla_trunk_ref *trunk_ref;
+	struct sla_station_ref *station_ref;
+
 	ast_mutex_lock(&sla.lock);
-	ast_cond_signal(&sla.cond);
+
+	/* Make sure that every station that uses at least one of the ringing
+	 * trunks, is ringing. */
+	AST_LIST_TRAVERSE(&sla.ringing_trunks, trunk_ref, entry) {
+		AST_LIST_TRAVERSE(&trunk_ref->trunk->stations, station_ref, entry) {
+			char *tech, *tech_data;
+			struct ast_dial *dial;
+			struct sla_station_ref *ringing_ref;
+			struct sla_failed_station *failed_station;
+			/* Did we fail to dial this station earlier?  If so, has it been
+ 			 * a minute since we tried? */
+			AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.failed_stations, failed_station, entry) {
+				if (station_ref->station != failed_station->station)
+					continue;
+				if (ast_tvdiff_ms(ast_tvnow(), failed_station->last_try) > 1000) {
+					AST_LIST_REMOVE_CURRENT(&sla.failed_stations, entry);
+					free(failed_station);
+					failed_station = NULL;
+				}
+				break;
+			}
+			if (failed_station)
+				continue;
+			AST_LIST_TRAVERSE_SAFE_END
+			AST_LIST_TRAVERSE(&sla.ringing_stations, ringing_ref, entry) {
+				if (station_ref->station == ringing_ref->station)
+					break;
+			}
+			if (ringing_ref)
+				continue;
+			if (!(dial = ast_dial_create()))
+				continue;
+			ast_dial_set_state_callback(dial, sla_dial_state_callback);
+			tech_data = ast_strdupa(station_ref->station->device);
+			tech = strsep(&tech_data, "/");
+			if (ast_dial_append(dial, tech, tech_data) == -1) {
+				ast_dial_destroy(dial);
+				continue;
+			}
+			if (ast_dial_run(dial, trunk_ref->trunk->chan, 1) != AST_DIAL_RESULT_TRYING) {
+				ast_dial_destroy(dial);
+				if (!(failed_station = ast_calloc(1, sizeof(*failed_station))))
+					continue;
+				failed_station->station = station_ref->station;
+				failed_station->last_try = ast_tvnow();
+				AST_LIST_INSERT_HEAD(&sla.failed_stations, failed_station, entry);
+				continue;
+			}
+			if (!(ringing_ref = create_station_ref(station_ref->station))) {
+				ast_dial_join(dial);
+				ast_dial_destroy(dial);
+				continue;
+			}
+			station_ref->station->dial = dial;
+			AST_LIST_INSERT_HEAD(&sla.ringing_stations, ringing_ref, entry);
+			ast_log(LOG_DEBUG, "Started dialing station '%s'\n", station_ref->station->name);
+		}
+	}
 	ast_mutex_unlock(&sla.lock);
+	/* Now, all of the stations that should be ringing, are ringing. */
+	
+	/* Find stations that shouldn't be ringing anymore. */
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, station_ref, entry) {
+		AST_LIST_TRAVERSE(&station_ref->station->trunks, trunk_ref, entry) {
+			struct sla_trunk_ref *ringing_ref;
+			ast_mutex_lock(&sla.lock);
+			AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_ref, entry) {
+				if (trunk_ref->trunk == ringing_ref->trunk)
+					break;
+			}
+			ast_mutex_unlock(&sla.lock);
+			if (ringing_ref)
+				break;
+		}
+		if (!trunk_ref) {
+			AST_LIST_REMOVE_CURRENT(&sla.ringing_stations, entry);
+			ast_dial_join(station_ref->station->dial);
+			ast_dial_destroy(station_ref->station->dial);
+			station_ref->station->dial = NULL;
+			free(station_ref);
+		}
+	}
+	AST_LIST_TRAVERSE_SAFE_END
+}
+
+static void sla_handle_hold_event(struct sla_event *event)
+{
+	ast_atomic_fetchadd_int((int *) &event->trunk_ref->trunk->hold_stations, 1);
+	event->trunk_ref->state = SLA_TRUNK_STATE_ONHOLD;
+	ast_device_state_changed("SLA:%s_%s", 
+		event->station->name, event->trunk_ref->trunk->name);
+	change_trunk_state(event->trunk_ref->trunk, SLA_TRUNK_STATE_ONHOLD, 1);	
+}
+
+static void sla_handle_unhold_event(struct sla_event *event)
+{
+	if (ast_atomic_dec_and_test((int *) &event->trunk_ref->trunk->hold_stations) == 1)
+		change_trunk_state(event->trunk_ref->trunk, SLA_TRUNK_STATE_UP, 0);
+	else {
+		event->trunk_ref->state = SLA_TRUNK_STATE_UP;
+		ast_device_state_changed("SLA:%s_%s",
+			event->station->name, event->trunk_ref->trunk->name);
+	}
 }
 
 static void *sla_thread(void *data)
 {
-	AST_LIST_HEAD_NOLOCK_STATIC(ringing_stations, sla_station_ref);
-	struct sla_failed_station {
-		struct sla_station *station;
-		struct timeval last_try;
-		AST_LIST_ENTRY(sla_failed_station) entry;
-	};
-	AST_LIST_HEAD_NOLOCK_STATIC(failed_stations, sla_failed_station);
+	struct sla_failed_station *failed_station;
 	struct sla_station_ref *station_ref;
-	struct sla_failed_station *failed_station;
 
 	ast_mutex_lock(&sla.lock);
 
-	for (; !sla.stop;) {
-		struct sla_trunk_ref *trunk_ref = NULL;
+	while (!sla.stop) {
 		struct sla_event *event;
-		enum ast_dial_result dial_res = AST_DIAL_RESULT_TRYING;
-
-		ast_cond_wait(&sla.cond, &sla.lock);
-		if (sla.stop)
-			break;
+
+		if (AST_LIST_EMPTY(&sla.event_q)) {
+			ast_cond_wait(&sla.cond, &sla.lock);
+			if (sla.stop)
+				break;
+			ast_log(LOG_DEBUG, "Ooh, I was woken up!\n");
+		}
 
 		while ((event = AST_LIST_REMOVE_HEAD(&sla.event_q, entry))) {
+			ast_mutex_unlock(&sla.lock);
 			switch (event->type) {
 			case SLA_EVENT_HOLD:
-				ast_log(LOG_DEBUG, "HOLD, station: %s  trunk: %s\n", 
-					event->station->name, event->trunk_ref->trunk->name);
-				ast_atomic_fetchadd_int((int *) &event->trunk_ref->trunk->hold_stations, 1);
-				event->trunk_ref->state = SLA_TRUNK_STATE_ONHOLD;
-				ast_device_state_changed("SLA:%s_%s", 
-					event->station->name, event->trunk_ref->trunk->name);
-				change_trunk_state(event->trunk_ref->trunk, SLA_TRUNK_STATE_ONHOLD, 1);	
+				sla_handle_hold_event(event);
 				break;
 			case SLA_EVENT_UNHOLD:
-				ast_log(LOG_DEBUG, "UNHOLD, station: %s  trunk: %s\n", 
-					event->station->name, event->trunk_ref->trunk->name);
-				if (ast_atomic_dec_and_test((int *) &event->trunk_ref->trunk->hold_stations) == 1)
-					change_trunk_state(event->trunk_ref->trunk, SLA_TRUNK_STATE_UP, 0);
-				else {
-					event->trunk_ref->state = SLA_TRUNK_STATE_UP;
-					ast_device_state_changed("SLA:%s_%s",
-						event->station->name, event->trunk_ref->trunk->name);
-				}
+				sla_handle_unhold_event(event);				
 				break;
+			case SLA_EVENT_DIAL_STATE:
+				sla_handle_dial_state_event();
+				break;
+			case SLA_EVENT_RINGING_TRUNK:
+				sla_handle_ringing_trunk_event();
+				break;
 			}
 			free(event);
-		}
-
-		/* At this point, we know there are ringing trunks.  So, make sure that every
-		 * station that uses at least one of the ringing trunks, is ringing. */
-		AST_LIST_TRAVERSE(&sla.ringing_trunks, trunk_ref, entry) {
-			AST_LIST_TRAVERSE(&trunk_ref->trunk->stations, station_ref, entry) {
-				char *tech, *tech_data;
-				struct ast_dial *dial;
-				struct sla_station_ref *ringing_ref;
-				struct sla_failed_station *failed_station;
-				/* Did we fail to dial this station earlier?  If so, has it been
- 				 * a minute since we tried? */
-				AST_LIST_TRAVERSE_SAFE_BEGIN(&failed_stations, failed_station, entry) {
-					if (station_ref->station != failed_station->station)
-						continue;
-					if (ast_tvdiff_ms(ast_tvnow(), failed_station->last_try) > 1000) {
-						AST_LIST_REMOVE_CURRENT(&failed_stations, entry);
-						free(failed_station);
-						failed_station = NULL;
-					}
-					break;
-				}
-				if (failed_station)
-					continue;
-				AST_LIST_TRAVERSE_SAFE_END
-				AST_LIST_TRAVERSE(&ringing_stations, ringing_ref, entry) {
-					if (station_ref->station == ringing_ref->station)
-						break;
-				}
-				if (ringing_ref)
-					continue;
-				if (!(dial = ast_dial_create()))
-					continue;
-				ast_dial_set_state_callback(dial, sla_dial_state_callback);
-				tech_data = ast_strdupa(station_ref->station->device);
-				tech = strsep(&tech_data, "/");
-				if (ast_dial_append(dial, tech, tech_data) == -1) {
-					ast_dial_destroy(dial);
-					continue;
-				}
-				if (ast_dial_run(dial, trunk_ref->trunk->chan, 1) != AST_DIAL_RESULT_TRYING) {
-					ast_dial_destroy(dial);
-					if (!(failed_station = ast_calloc(1, sizeof(*failed_station))))
-						continue;
-					failed_station->station = station_ref->station;
-					failed_station->last_try = ast_tvnow();
-					AST_LIST_INSERT_HEAD(&failed_stations, failed_station, entry);
-					continue;
-				}
-				if (!(ringing_ref = create_station_ref(station_ref->station))) {
-					ast_dial_join(dial);
-					ast_dial_destroy(dial);
-					continue;
-				}
-				station_ref->station->dial = dial;
-				AST_LIST_INSERT_HEAD(&ringing_stations, ringing_ref, entry);
-				ast_log(LOG_DEBUG, "Started dialing station '%s'\n", station_ref->station->name);
-			}
-		}
-		/* Now, all of the stations that should be ringing, are ringing. */
-		
-		AST_LIST_TRAVERSE_SAFE_BEGIN(&ringing_stations, station_ref, entry) {
-			struct sla_trunk_ref *s_trunk_ref;
-			struct run_station_args args;
-			pthread_attr_t attr;
-			pthread_t dont_care;
-			ast_mutex_t cond_lock;
-			ast_cond_t cond;
-
-			switch ((dial_res = ast_dial_state(station_ref->station->dial))) {
-			case AST_DIAL_RESULT_HANGUP:
-			case AST_DIAL_RESULT_INVALID:
-			case AST_DIAL_RESULT_FAILED:
-			case AST_DIAL_RESULT_TIMEOUT:
-			case AST_DIAL_RESULT_UNANSWERED:
-				AST_LIST_REMOVE_CURRENT(&ringing_stations, entry);
-				ast_dial_join(station_ref->station->dial);
-				ast_dial_destroy(station_ref->station->dial);
-				station_ref->station->dial = NULL;
-				free(station_ref);
-				break;
-			case AST_DIAL_RESULT_ANSWERED:
-				AST_LIST_REMOVE_CURRENT(&ringing_stations, entry);
-				/* Find the appropriate trunk to answer. */
-				AST_LIST_TRAVERSE(&station_ref->station->trunks, s_trunk_ref, entry) {
-					AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, trunk_ref, entry) {
-						if (s_trunk_ref->trunk == trunk_ref->trunk) {
-							AST_LIST_REMOVE_CURRENT(&sla.ringing_trunks, entry);
-							break;
-						}
-					}
-					AST_LIST_TRAVERSE_SAFE_END
-					if (trunk_ref)
-						break;
-				}
-				if (!trunk_ref) {
-					ast_log(LOG_DEBUG, "Found no ringing trunk for station '%s' to answer!\n",
-						station_ref->station->name);
-					break;
-				}
-				s_trunk_ref->chan = ast_dial_answered(station_ref->station->dial);
-				ast_answer(trunk_ref->trunk->chan);
-				change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, 0);
-				args.trunk_ref = s_trunk_ref;
-				args.station = station_ref->station;
-				args.cond = &cond;
-				args.cond_lock = &cond_lock;
-				free(trunk_ref);
-				free(station_ref);
-				ast_mutex_init(&cond_lock);
-				ast_cond_init(&cond, NULL);
-				pthread_attr_init(&attr);
-				pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-				ast_mutex_lock(&cond_lock);
-				ast_pthread_create_background(&dont_care, &attr, run_station, &args);
-				ast_cond_wait(&cond, &cond_lock);
-				ast_mutex_unlock(&cond_lock);
-				ast_mutex_destroy(&cond_lock);
-				ast_cond_destroy(&cond);
-				pthread_attr_destroy(&attr);
-				break;
-			case AST_DIAL_RESULT_TRYING:
-			case AST_DIAL_RESULT_RINGING:
-			case AST_DIAL_RESULT_PROGRESS:
-			case AST_DIAL_RESULT_PROCEEDING:
-				break;
-			}
-			if (dial_res == AST_DIAL_RESULT_ANSWERED || !AST_LIST_EMPTY(&sla.event_q))
-				break;
-		}
-		AST_LIST_TRAVERSE_SAFE_END
-		/* Find stations that shouldn't be ringing anymore. */
-		AST_LIST_TRAVERSE_SAFE_BEGIN(&ringing_stations, station_ref, entry) {
-			AST_LIST_TRAVERSE(&station_ref->station->trunks, trunk_ref, entry) {
-				struct sla_trunk_ref *ringing_ref;
-				AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_ref, entry) {
-					if (trunk_ref->trunk == ringing_ref->trunk)
-						break;
-				}
-				if (ringing_ref)
-					break;
-			}
-			if (!trunk_ref) {
-				AST_LIST_REMOVE_CURRENT(&ringing_stations, entry);
-				ast_dial_join(station_ref->station->dial);
-				ast_dial_destroy(station_ref->station->dial);
-				station_ref->station->dial = NULL;
-				free(station_ref);
-			}
-		}
-		AST_LIST_TRAVERSE_SAFE_END
+			ast_mutex_lock(&sla.lock);
+		}
 	}
 
 	ast_mutex_unlock(&sla.lock);
 
-	while ((station_ref = AST_LIST_REMOVE_HEAD(&ringing_stations, entry)))
+	while ((station_ref = AST_LIST_REMOVE_HEAD(&sla.ringing_stations, entry)))
 		free(station_ref);
 
-	while ((failed_station = AST_LIST_REMOVE_HEAD(&failed_stations, entry)))
+	while ((failed_station = AST_LIST_REMOVE_HEAD(&sla.failed_stations, entry)))
 		free(failed_station);
 
 	return NULL;
@@ -3496,8 +3554,8 @@
 	change_trunk_state(trunk, SLA_TRUNK_STATE_RINGING, 0);
 
 	ast_mutex_lock(&sla.lock);
-	ast_cond_signal(&sla.cond);
 	AST_LIST_INSERT_HEAD(&sla.ringing_trunks, trunk_ref, entry);
+	sla_queue_event(SLA_EVENT_RINGING_TRUNK);
 	ast_mutex_unlock(&sla.lock);
 
 	snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk_name);

Modified: team/russell/sla_updates/doc/sla.txt
URL: http://svn.digium.com/view/asterisk/team/russell/sla_updates/doc/sla.txt?view=diff&rev=54437&r1=54436&r2=54437
==============================================================================
--- team/russell/sla_updates/doc/sla.txt (original)
+++ team/russell/sla_updates/doc/sla.txt Wed Feb 14 12:16:18 2007
@@ -1,17 +1,17 @@
--------------------------------------------------------------
---- Shared Line Appearances ---------------------------------
--------------------------------------------------------------
+-------------------------------------------------------------------------------
+--- Shared Line Appearances ---------------------------------------------------
+-------------------------------------------------------------------------------
 
--------------------------------------------------------------
+-------------------------------------------------------------------------------
 INTRODUCTION
 
 The "SLA" functionality in Asterisk is intended to allow a setup that emulates
 a simple key system.  It uses the various abstraction layers already built into
 Asterisk to emulate key system functionality across various devices, including
 IP channels.
--------------------------------------------------------------
+-------------------------------------------------------------------------------
 
--------------------------------------------------------------
+-------------------------------------------------------------------------------
 DIALPLAN CONFIGURATION
 
 The SLA implementation can automatically generate the dialplan necessary for
@@ -44,9 +44,9 @@
 exten => station3_line1,1,SLAStation(station3_line1)
 exten => station3_line2,hint,SLA:station3_line2
 exten => station3_line2,1,SLAStation(station3_line2)
--------------------------------------------------------------
+-------------------------------------------------------------------------------
 
--------------------------------------------------------------
+-------------------------------------------------------------------------------
 TRUNKS
 
 For the trunk side of SLA, the only channels that are currently supported are
@@ -57,10 +57,10 @@
 
 If the dialplan is being built manually, ensure that calls coming in on a trunk
 execute the SLATrunk() application with an argument of the trunk name.
--------------------------------------------------------------
+-------------------------------------------------------------------------------
 
 
--------------------------------------------------------------
+-------------------------------------------------------------------------------
 STATIONS
 
 Currently, the only channel driver that has all of the features necessary to
@@ -90,4 +90,4 @@
    c) If you would like the phone to automatically connect to a trunk when it
       is taken off hook, then the phone should be automatically configured to
       dial "station1" when it is taken off hook.
--------------------------------------------------------------
+-------------------------------------------------------------------------------



More information about the asterisk-commits mailing list