[asterisk-commits] jpeeler: branch jpeeler/dahdi-restart r136788 - /team/jpeeler/dahdi-restart/c...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Aug 8 11:13:06 CDT 2008


Author: jpeeler
Date: Fri Aug  8 11:13:06 2008
New Revision: 136788

URL: http://svn.digium.com/view/asterisk?view=rev&rev=136788
Log:
good check in point, code tested to be working with analog, PRI, and SS7. clean up time\!

Modified:
    team/jpeeler/dahdi-restart/channels/chan_dahdi.c

Modified: team/jpeeler/dahdi-restart/channels/chan_dahdi.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/dahdi-restart/channels/chan_dahdi.c?view=diff&rev=136788&r1=136787&r2=136788
==============================================================================
--- team/jpeeler/dahdi-restart/channels/chan_dahdi.c (original)
+++ team/jpeeler/dahdi-restart/channels/chan_dahdi.c Fri Aug  8 11:13:06 2008
@@ -283,6 +283,7 @@
 static int mwi_thread_count = 0;
 static int ss_thread_count = 0;
 static int restart_pending = 0;
+static int num_restart_pending = 0;
 
 static int restart_monitor(void);
 
@@ -566,6 +567,7 @@
 	unsigned int priexclusive:1;
 	unsigned int pulse:1;
 	unsigned int pulsedial:1;			/*!< whether a pulse dial phone is detected */
+	unsigned int restartpending:1;		/*!< channel marked to be destroyed for restart */
 	unsigned int restrictcid:1;			/*!< Whether restrict the callerid -> only send ANI */
 	unsigned int threewaycalling:1;
 	unsigned int transfer:1;
@@ -911,7 +913,8 @@
 		}
 	} while (res);
 	/* Then break the poll */
-	pthread_kill(pri->master, SIGURG);
+	if (pri->master != AST_PTHREADT_NULL) /* if dahdi_hangup is called after monitor thread is stopped for restart */
+		pthread_kill(pri->master, SIGURG);
 	return 0;
 }
 #endif
@@ -1132,6 +1135,18 @@
 	return fd;
 }
 
+/*
+static int fd_status(int fd)
+{
+	int status;
+	status = fcntl(fd, F_GETFD);
+	if (status == -1 && errno == EBADF)
+		ast_log(LOG_WARNING, "**************** fd=%d NOT closed\n", fd);
+
+	return status;
+}
+*/
+
 static void dahdi_close(int fd)
 {
 	//int status;
@@ -1139,7 +1154,9 @@
 		close(fd);
 	//status = fcntl(fd, F_GETFD);
 	//if (status == -1)
-	//	ast_log(LOG_WARNING, "fd=%d is closed, that's good\n", fd);
+	//	ast_log(LOG_WARNING, "**************** fd=%d NOT closed\n", fd);
+	//else
+	//	ast_log(LOG_WARNING, "Close looks good %d for fd=%d\n", status, fd);
 }
 
 static int dahdi_setlinear(int zfd, int linear)
@@ -2773,6 +2790,9 @@
 static void destroy_dahdi_pvt(struct dahdi_pvt **pvt)
 {
 	struct dahdi_pvt *p = *pvt;
+
+	ast_mutex_lock(&p->lock);
+	ast_mutex_unlock(&p->lock);
 	/* Remove channel from the list */
 	if (p->prev)
 		p->prev->next = p->next;
@@ -2784,7 +2804,7 @@
 		ast_event_unsubscribe(p->mwi_event_sub);
 	if (p->vars)
 		ast_variables_destroy(p->vars);
-	ast_mutex_destroy(&p->lock);
+	//ast_mutex_destroy(&p->lock);
 	if (p->owner)
 		p->owner->tech_pvt = NULL;
 	//memset(p, 0, sizeof(*p));
@@ -2848,6 +2868,54 @@
 	return 0;
 }
 
+static void destroy_all_channels(void)
+{
+	int x;
+	struct dahdi_pvt *p, *pl;
+
+	while (num_restart_pending) {
+		usleep(1);
+	}
+
+	ast_mutex_lock(&iflock);
+ast_log(LOG_WARNING, "Num of channels = %d\n", ast_active_channels());
+	/* Destroy all the interfaces and free their memory */
+	p = iflist;
+	while (p) {
+		//while(p->owner)
+		//	;
+
+/*
+if (p->owner) {
+	for (x = 0; x < 10; x++) {
+		ast_log(LOG_WARNING, "p->owner=%p fd[%d]=%d\n", p->owner, x, p->owner->fds[x]);
+	}
+} else {
+	ast_log(LOG_WARNING, "No owner\n");
+}
+*/
+
+		/* Free any callerid */
+		if (p->cidspill)
+			ast_free(p->cidspill);
+		/* Close the DAHDI thingy */
+		if (p->subs[SUB_REAL].zfd > -1)
+			dahdi_close(p->subs[SUB_REAL].zfd);
+		if (!p)
+			printf("Very bad\n");
+		pl = p;
+		p = p->next;
+		x = pl->channel;
+		/* Free associated memory */
+		if (pl)
+			destroy_dahdi_pvt(&pl);
+		ast_verb(3, "Unregistered channel %d\n", x);
+	}
+	iflist = NULL;
+	ifcount = 0;
+	ast_mutex_unlock(&iflock);
+}
+
 #ifdef HAVE_PRI
 static char *dahdi_send_keypad_facility_app = "DAHDISendKeypadFacility";
 
@@ -2991,6 +3059,11 @@
 		ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
 		return 0;
 	}
+
+#ifdef HAVE_SS7
+	if (p->alreadyhungup)
+		return 0;
+#endif	
 	
 	ast_mutex_lock(&p->lock);
 	
@@ -3311,6 +3384,11 @@
 	ast_verb(3, "Hungup '%s'\n", ast->name);
 
 	ast_mutex_lock(&iflock);
+
+	if (p->restartpending) {
+		num_restart_pending--;
+	}
+
 	tmp = iflist;
 	prev = NULL;
 	if (p->destroy) {
@@ -3323,8 +3401,12 @@
 				tmp = tmp->next;
 			}
 		}
-	}
+	} else {
+		//ast_log(LOG_WARNING, "******************* Important, not destroyed here\n");
+	}
+
 	ast_mutex_unlock(&iflock);
+
 	return 0;
 }
 
@@ -11935,12 +12017,30 @@
 	struct dahdi_pvt *p;
 	ast_verb(1, "Destroying channels and reloading DAHDI configuration.\n");
 
-	p = iflist;
-    while (p) {
-        if (p->owner)
-            ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
-        p = p->next;
+#if 1
+retry1:
+	ast_mutex_lock(&iflock);
+    for (p = iflist; p; p = p->next) {
+		ast_mutex_lock(&p->lock);
+        if (p->owner && !p->restartpending) {
+			if (ast_channel_trylock(p->owner)) {
+			ast_log(LOG_WARNING, "Avoiding deadlock\n");
+				/* Avoid deadlock since you're not supposed to lock iflock or pvt before a channel */
+				ast_mutex_unlock(&p->lock);
+				ast_mutex_unlock(&iflock);
+				goto retry1;
+			}
+			ast_log(LOG_WARNING, "1: Softhanging up on %s\n", p->owner->name);
+			ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_EXPLICIT);
+			p->restartpending = 1;
+			num_restart_pending++;
+			ast_channel_unlock(p->owner);
+		}
+		ast_mutex_unlock(&p->lock);
     }
+	ast_mutex_unlock(&iflock);
+	ast_verb(1, "Initial softhangup of all DAHDI channels complete.\n");
+#endif
 
 	#if defined(HAVE_PRI)
     for (i = 0; i < NUM_SPANS; i++) {
@@ -11976,7 +12076,39 @@
 	#endif /* HAVE_PRI */
 
 	#if defined(HAVE_SS7)
-
+	for (i = 0; i < NUM_SPANS; i++) {
+		if (linksets[i].master && (linksets[i].master != AST_PTHREADT_NULL)) {
+			cancel_code = pthread_cancel(linksets[i].master);
+			pthread_kill(linksets[i].master, SIGURG);
+			ast_log(LOG_WARNING, "Waiting to join thread of span %d with pid=%p cancel_code=%d\n", i, (void *) linksets[i].master, cancel_code);
+			pthread_join(linksets[i].master, NULL);
+			ast_log(LOG_WARNING, "Joined thread of span %d\n", i);
+		}
+//		for (j = 0; j < linksets[i].numchans - 1; j++) {
+//			struct dahdi_pvt *p = linksets[i].pvts[j];
+//			if (p->ss7) {
+//				if (p->ss7call) {
+//	/* jpeeler: may need to lock here, was done by ss7_grab previously */
+//					if (!p->alreadyhungup) {
+///*
+//						const char *cause = pbx_builtin_getvar_helper(ast,"SS7_CAUSE");
+//						int icause = ast->hangupcause ? ast->hangupcause : -1;
+//
+//						if (cause) {
+//							if (atoi(cause))
+//								icause = atoi(cause);
+//						}
+//
+//						//isup_rel(p->ss7->ss7, p->ss7call, 8);
+//						//ss7_rel(p->ss7);
+//						p->alreadyhungup = 1;
+//						p->owner->tech_pvt = NULL;
+//					} else
+//						ast_log(LOG_WARNING, "Trying to hangup twice!\n");
+//				}
+//			}
+//		}
+	}
 	#endif /* HAVE_SS7 */
 
 	restart_pending = 1;
@@ -12013,14 +12145,51 @@
 	}
 
 	//restart_pending = 1;
+	/*
 	while (iflist) {
 		ast_debug(1, "Destroying DAHDI channel no. %d\n", iflist->channel);
-		/* Also updates iflist: */
+		// Also updates iflist: 
 		destroy_channel(NULL, iflist, 1);
 	}
+	*/
+
+#if 1
+	/* ensure any created channels before monitor threads were stopped are hungup */
+retry:
+	ast_mutex_lock(&iflock);
+    for (p = iflist; p; p = p->next) {
+		ast_mutex_lock(&p->lock);
+        if (p->owner && !p->restartpending) {
+			if (ast_channel_trylock(p->owner)) {
+				/* Avoid deadlock since you're not supposed to lock iflock or pvt before a channel */
+			ast_log(LOG_WARNING, "Avoiding deadlock\n");
+				ast_mutex_unlock(&p->lock);
+				ast_mutex_unlock(&iflock);
+				goto retry;
+			}
+			ast_log(LOG_WARNING, "2: Softhanging up on %s\n", p->owner->name);
+			ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_EXPLICIT);
+			p->restartpending = 1;
+			num_restart_pending++;
+			ast_channel_unlock(p->owner);
+		}
+		ast_mutex_unlock(&p->lock);
+    }
+	ast_mutex_unlock(&iflock);
+	ast_verb(1, "Final softhangup of all DAHDI channels complete.\n");
+#endif
+
+
+	destroy_all_channels();
+ast_log(LOG_WARNING, "After destruction: Num of channels = %d\n", ast_active_channels());
 	ast_debug(1, "Channels destroyed. Now re-reading config.\n");
+//while (ast_active_channels())
+//	ast_log(LOG_DEBUG, "Kept on waiting\n");
 
     ast_mutex_unlock(&monlock);
+
+	//while (ast_active_channels())
+	//	ast_log(LOG_WARNING, "Num of channels = %d\n", ast_active_channels());
 
 	#ifdef HAVE_PRI
 	for (i = 0; i < NUM_SPANS; i++) {
@@ -12040,6 +12209,11 @@
 	pri_set_message(dahdi_pri_message);
 	#endif
 	#ifdef HAVE_SS7
+	for (i = 0; i < NUM_SPANS; i++) {
+		for (j = 0; j < NUM_DCHANS; j++)
+        	dahdi_close(linksets[i].fds[j]);
+	}
+
 	memset(linksets, 0, sizeof(linksets));
 	for (i = 0; i < NUM_SPANS; i++) {
 		ast_mutex_init(&linksets[i].lock);
@@ -12060,6 +12234,7 @@
 	}
 	ast_mutex_unlock(&ss_thread_lock);
 	//restart_pending = 0;
+ast_log(LOG_WARNING, "End: Num of channels = %d\n", ast_active_channels());
 	return 0;
 }
 
@@ -13438,9 +13613,9 @@
 
 static int __unload_module(void)
 {
-	struct dahdi_pvt *p, *pl;
+	struct dahdi_pvt *p;
 #if defined(HAVE_PRI) || defined(HAVE_SS7)
-	int i, j, x;
+	int i, j;
 #endif
 
 #if defined(HAVE_PRI)
@@ -13455,7 +13630,7 @@
 #if defined(HAVE_SS7)
 	for (i = 0; i < NUM_SPANS; i++) {
 		if (linksets[i].master != AST_PTHREADT_NULL)
-			pthread_cancel(linksets[i].master );
+			pthread_cancel(linksets[i].master);
 	}
 	ast_cli_unregister_multiple(dahdi_ss7_cli, sizeof(dahdi_ss7_cli) / sizeof(struct ast_cli_entry));
 #endif
@@ -13487,28 +13662,7 @@
 	monitor_thread = AST_PTHREADT_STOP;
 	ast_mutex_unlock(&monlock);
 
-	ast_mutex_lock(&iflock);
-	/* Destroy all the interfaces and free their memory */
-	p = iflist;
-	while (p) {
-		/* Free any callerid */
-		if (p->cidspill)
-			ast_free(p->cidspill);
-		/* Close the DAHDI thingy */
-		if (p->subs[SUB_REAL].zfd > -1)
-			dahdi_close(p->subs[SUB_REAL].zfd);
-		pl = p;
-		p = p->next;
-		x = pl->channel;
-		/* Free associated memory */
-		if (pl)
-			destroy_dahdi_pvt(&pl);
-		ast_verb(3, "Unregistered channel %d\n", x);
-	}
-	iflist = NULL;
-	ifcount = 0;
-	ast_mutex_unlock(&iflock);
-
+	destroy_all_channels();
 #if defined(HAVE_PRI)
 	for (i = 0; i < NUM_SPANS; i++) {
 		if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))




More information about the asterisk-commits mailing list