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
  ........
................


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.2@218576 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.6.2
Jeff Peeler 17 years ago
parent 820404f666
commit cd2e56cada

@ -1395,7 +1395,7 @@ static int dahdi_indicate(struct ast_channel *chan, int condition, const void *d
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 @@ static int dahdi_destroy_channel_bynum(int channel)
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 @@ static int handle_init_event(struct dahdi_pvt *i, int event)
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 @@ static int handle_init_event(struct dahdi_pvt *i, int event)
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 @@ static int handle_init_event(struct dahdi_pvt *i, int event)
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 @@ static int handle_init_event(struct dahdi_pvt *i, int event)
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 @@ static int handle_init_event(struct dahdi_pvt *i, int event)
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 @@ static int handle_init_event(struct dahdi_pvt *i, int event)
"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 @@ static int handle_init_event(struct dahdi_pvt *i, int event)
}
break;
}
return thread_spawned;
return NULL;
}
static void *do_monitor(void *data)
@ -9467,6 +9458,7 @@ static void *do_monitor(void *data)
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 @@ static void *do_monitor(void *data)
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 @@ static void *do_monitor(void *data)
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 @@ static void *do_monitor(void *data)
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 @@ static void *do_monitor(void *data)
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 @@ static void *do_monitor(void *data)
/* 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);
}

Loading…
Cancel
Save