[asterisk-commits] jpeeler: branch 1.6.2 r218576 - in /branches/1.6.2: ./ channels/chan_dahdi.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Sep 15 10:59:50 CDT 2009


Author: jpeeler
Date: Tue Sep 15 10:59:45 2009
New Revision: 218576

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=218576
Log:
Merged revisions 218430 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
  r218430 | jpeeler | 2009-09-14 17:38:25 -0500 (Mon, 14 Sep 2009) | 18 lines
  
  Merged revisions 218401 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r218401 | jpeeler | 2009-09-14 16:47:11 -0500 (Mon, 14 Sep 2009) | 11 lines
    
    Fix handling of DAHDI_EVENT_REMOVED event to prevent crash in do_monitor.
    
    After talking to rmudgett about some of his recent iflist locking changes, it
    was determined that the only place that would destroy a channel without being
    explicitly to do so was in handle_init_event. The loop to walk the interface
    list has been modified to wait to destroy the channel until the dahdi_pvt of
    the channel to be destroyed is no longer needed.
    
    (closes issue #15378)
    Reported by: samy
  ........
................

Modified:
    branches/1.6.2/   (props changed)
    branches/1.6.2/channels/chan_dahdi.c

Propchange: branches/1.6.2/
------------------------------------------------------------------------------
Binary property 'trunk-merged' - no diff available.

Modified: branches/1.6.2/channels/chan_dahdi.c
URL: http://svn.asterisk.org/svn-view/asterisk/branches/1.6.2/channels/chan_dahdi.c?view=diff&rev=218576&r1=218575&r2=218576
==============================================================================
--- branches/1.6.2/channels/chan_dahdi.c (original)
+++ branches/1.6.2/channels/chan_dahdi.c Tue Sep 15 10:59:45 2009
@@ -1395,7 +1395,7 @@
 static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
 static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen);
 static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len);
-static int handle_init_event(struct dahdi_pvt *i, int event);
+static struct dahdi_pvt *handle_init_event(struct dahdi_pvt *i, int event);
 
 static const struct ast_channel_tech dahdi_tech = {
 	.type = "DAHDI",
@@ -9226,11 +9226,9 @@
 	return RESULT_FAILURE;
 }
 
-/* returns < 0 = error, 0 event handled, >0 event handled and thread spawned */
-static int handle_init_event(struct dahdi_pvt *i, int event)
+static struct dahdi_pvt *handle_init_event(struct dahdi_pvt *i, int event)
 {
 	int res;
-	int thread_spawned = 0;
 	pthread_t threadid;
 	struct ast_channel *chan;
 
@@ -9285,8 +9283,6 @@
 						if (res < 0)
 							ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
 						ast_hangup(chan);
-					} else {
-						thread_spawned = 1;
 					}
 				} else
 					ast_log(LOG_WARNING, "Unable to create channel\n");
@@ -9328,8 +9324,6 @@
 					ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
 				}
 				ast_hangup(chan);
-			} else {
-				thread_spawned = 1;
 			}
 			break;
 		default:
@@ -9337,7 +9331,7 @@
 			res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
 			if (res < 0)
 				ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
-			return -1;
+			return NULL;
 		}
 		break;
 	case DAHDI_EVENT_NOALARM:
@@ -9402,7 +9396,7 @@
 		default:
 			ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
 			res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
-			return -1;
+			return NULL;
 		}
 		if (i->sig & __DAHDI_SIG_FXO) {
 			i->fxsoffhookstate = 0;
@@ -9429,8 +9423,6 @@
 					ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
 				} else if (ast_pthread_create_detached(&threadid, NULL, ss_thread, chan)) {
 					ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
-				} else {
-					thread_spawned = 1;
 				}
 			}
 			break;
@@ -9440,12 +9432,11 @@
 				"interface %d\n", i->channel);
 		}
 		break;
-	case DAHDI_EVENT_REMOVED: /* destroy channel */
+	case DAHDI_EVENT_REMOVED: /* destroy channel, will actually do so in do_monitor */
 		ast_log(LOG_NOTICE,
 				"Got DAHDI_EVENT_REMOVED. Destroying channel %d\n",
 				i->channel);
-		dahdi_destroy_channel_bynum(i->channel);
-		break;
+		return i;
 	case DAHDI_EVENT_NEONMWI_ACTIVE:
 		if (i->mwimonitor_neon) {
 			notify_message(i->mailbox, 1);
@@ -9459,7 +9450,7 @@
 		}
 		break;
 	}
-	return thread_spawned;
+	return NULL;
 }
 
 static void *do_monitor(void *data)
@@ -9467,6 +9458,7 @@
 	int count, res, res2, spoint, pollres=0;
 	struct dahdi_pvt *i;
 	struct dahdi_pvt *last = NULL;
+	struct dahdi_pvt *doomed;
 	time_t thispass = 0, lastpass = 0;
 	int found;
 	char buf[1024];
@@ -9544,7 +9536,20 @@
 		lastpass = thispass;
 		thispass = time(NULL);
 		i = iflist;
-		while (i) {
+		doomed = NULL;
+		for (i = iflist;; i = i->next) {
+			if (doomed) {
+				int res;
+				res = dahdi_destroy_channel_bynum(doomed->channel);
+				if (!res) {
+					ast_log(LOG_WARNING, "Couldn't find channel to destroy, hopefully another destroy operation just happened.\n");
+				}
+				doomed = NULL;
+			}
+			if (!i) {
+				break;
+			}
+
 			if (thispass != lastpass) {
 				if (!found && ((i == last) || ((i == iflist) && !last))) {
 					last = i;
@@ -9582,10 +9587,9 @@
 						ast_debug(1, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
 						/* Don't hold iflock while handling init events */
 						ast_mutex_unlock(&iflock);
-						handle_init_event(i, res);
+						doomed = handle_init_event(i, res);
 						ast_mutex_lock(&iflock);
 					}
-					i = i->next;
 					continue;
 				}
 				pollres = ast_fdisset(pfds, i->subs[SUB_REAL].dfd, count, &spoint);
@@ -9595,12 +9599,10 @@
 						if (!i->pri)
 #endif
 							ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].dfd);
-						i = i->next;
 						continue;
 					}
 					if (!i->mwimonitor_fsk && !i->mwisendactive) {
 						ast_log(LOG_WARNING, "Whoa....  I'm not looking for MWI or sending MWI but am reading (%d)...\n", i->subs[SUB_REAL].dfd);
-						i = i->next;
 						continue;
 					}
 					res = read(i->subs[SUB_REAL].dfd, buf, sizeof(buf));
@@ -9640,7 +9642,6 @@
 						if (!i->pri)
 #endif
 							ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].dfd);
-						i = i->next;
 						continue;
 					}
 					res = dahdi_get_event(i->subs[SUB_REAL].dfd);
@@ -9648,12 +9649,11 @@
 					/* Don't hold iflock while handling init events */
 					ast_mutex_unlock(&iflock);
 					if (0 == i->mwisendactive || 0 == mwi_send_process_event(i, res)) {
-						handle_init_event(i, res);
+						doomed = handle_init_event(i, res);
 					}
 					ast_mutex_lock(&iflock);
 				}
 			}
-			i=i->next;
 		}
 		ast_mutex_unlock(&iflock);
 	}




More information about the asterisk-commits mailing list