[asterisk-commits] tilghman: branch tilghman/ast_select r281686 - /team/tilghman/ast_select/res/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Aug 11 00:34:22 CDT 2010
Author: tilghman
Date: Wed Aug 11 00:34:18 2010
New Revision: 281686
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=281686
Log:
Remove last remaining ast_select in code, and fix a few other bugs in the process.
Modified:
team/tilghman/ast_select/res/res_features.c
Modified: team/tilghman/ast_select/res/res_features.c
URL: http://svnview.digium.com/svn/asterisk/team/tilghman/ast_select/res/res_features.c?view=diff&rev=281686&r1=281685&r2=281686
==============================================================================
--- team/tilghman/ast_select/res/res_features.c (original)
+++ team/tilghman/ast_select/res/res_features.c Wed Aug 11 00:34:18 2010
@@ -525,7 +525,7 @@
}
}
- /* Wake up the (presumably select()ing) thread */
+ /* Wake up the (presumably poll()ing) thread */
pthread_kill(parking_thread, SIGURG);
/* Only say number if it's a number and the channel hasn't been masqueraded away */
@@ -2282,17 +2282,16 @@
/*! \brief Take care of parked calls and unpark them if needed */
static void *do_parking_thread(void *ignore)
{
- ast_fdset rfds, efds; /* results from previous select, to be preserved across loops. */
- FD_ZERO(&rfds);
- FD_ZERO(&efds);
+ /* results from previous poll, to be preserved across loops. */
+ struct pollfd *fds = NULL;
+ int nfds = 0;
+ struct timeval tv;
for (;;) {
struct parkeduser *pu, *pl, *pt = NULL;
- int ms = -1; /* select timeout, uninitialized */
- int max = -1; /* max fd, none there yet */
- ast_fdset nrfds, nefds; /* args for the next select */
- FD_ZERO(&nrfds);
- FD_ZERO(&nefds);
+ int ms = -1; /* poll2 timeout, uninitialized */
+ struct pollfd *new_fds = NULL;
+ int new_nfds = 0;
ast_mutex_lock(&parking_lock);
pl = NULL;
@@ -2314,25 +2313,24 @@
ast_indicate(chan, AST_CONTROL_UNHOLD);
/* Get chan, exten from derived kludge */
if (pu->peername[0]) {
+ /* Don't use ast_strdupa() inside an infinite loop */
char *peername = ast_strdup(pu->peername);
char *cp = strrchr(peername, '-');
- if (cp)
+ if (cp) {
*cp = 0;
- con = ast_context_find(parking_con_dial);
- if (!con) {
- con = ast_context_create(NULL, parking_con_dial, registrar);
- if (!con)
- ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", parking_con_dial);
}
- if (con) {
+ if (!(con = ast_context_find_or_create(NULL, parking_con_dial, registrar))) {
+ ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", parking_con_dial);
+ } else {
char returnexten[AST_MAX_EXTENSION];
struct ast_datastore *features_datastore;
struct ast_dial_features *dialfeatures = NULL;
ast_channel_lock(chan);
- if ((features_datastore = ast_channel_datastore_find(chan, &dial_features_info, NULL)))
+ if ((features_datastore = ast_channel_datastore_find(chan, &dial_features_info, NULL))) {
dialfeatures = features_datastore->data;
+ }
ast_channel_unlock(chan);
@@ -2341,7 +2339,7 @@
}
if (dialfeatures) {
- char buf[MAX_DIAL_FEATURE_OPTIONS] = {0,};
+ char buf[MAX_DIAL_FEATURE_OPTIONS] = "";
snprintf(returnexten, sizeof(returnexten), "%s|30|%s", peername, callback_dialoptions(&(dialfeatures->features_callee), &(dialfeatures->features_caller), buf, sizeof(buf)));
} else { /* Existing default */
ast_log(LOG_WARNING, "Dialfeatures not found on %s, using default!\n", chan->name);
@@ -2360,78 +2358,107 @@
post_manager_event("ParkedCallTimeOut", pu->parkingexten, chan);
- if (option_verbose > 1)
+ if (option_verbose > 1) {
ast_verbose(VERBOSE_PREFIX_2 "Timeout for %s parked on %d. Returning to %s,%s,%d\n", chan->name, pu->parkingnum, chan->context, chan->exten, chan->priority);
+ }
/* Start up the PBX, or hang them up */
if (ast_pbx_start(chan)) {
ast_log(LOG_WARNING, "Unable to restart the PBX for user on '%s', hanging them up...\n", chan->name);
ast_hangup(chan);
}
/* And take them out of the parking lot */
- if (pl)
+ if (pl) {
pl->next = pu->next;
- else
+ } else {
parkinglot = pu->next;
+ }
pt = pu;
pu = pu->next;
con = ast_context_find(parking_con);
if (con) {
- if (ast_context_remove_extension2(con, pt->parkingexten, 1, NULL))
+ if (ast_context_remove_extension2(con, pt->parkingexten, 1, NULL)) {
ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
- else
+ } else {
notify_metermaids(pt->parkingexten, parking_con);
- } else
+ }
+ } else {
ast_log(LOG_WARNING, "Whoa, no parking context?\n");
+ }
free(pt);
} else { /* still within parking time, process descriptors */
for (x = 0; x < AST_MAX_FDS; x++) {
struct ast_frame *f;
-
- if (chan->fds[x] == -1 || (!FD_ISSET(chan->fds[x], &rfds) && !FD_ISSET(chan->fds[x], &efds)))
+ int y;
+
+ if (chan->fds[x] == -1) {
continue; /* nothing on this descriptor */
-
- if (FD_ISSET(chan->fds[x], &efds))
+ }
+
+ for (y = 0; y < nfds; y++) {
+ if (fds[y].fd == chan->fds[x]) {
+ /* Found poll record! */
+ break;
+ }
+ }
+ if (y == nfds) {
+ /* Not found */
+ continue;
+ }
+
+ if (!(fds[y].revents & (POLLIN | POLLERR))) {
+ /* Next x */
+ continue;
+ }
+
+ if (fds[y].revents & POLLERR) {
ast_set_flag(chan, AST_FLAG_EXCEPTION);
- else
+ } else {
ast_clear_flag(chan, AST_FLAG_EXCEPTION);
+ }
chan->fdno = x;
/* See if they need servicing */
f = ast_read(chan);
if (!f || (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP)) {
- if (f)
+ if (f) {
ast_frfree(f);
+ }
post_manager_event("ParkedCallGiveUp", pu->parkingexten, chan);
/* There's a problem, hang them up*/
- if (option_verbose > 1)
+ if (option_verbose > 1) {
ast_verbose(VERBOSE_PREFIX_2 "%s got tired of being parked\n", chan->name);
- ast_hangup(chan);
+ }
/* And take them out of the parking lot */
- if (pl)
+ if (pl) {
pl->next = pu->next;
- else
+ } else {
parkinglot = pu->next;
+ }
pt = pu;
pu = pu->next;
+
+ ast_hangup(chan);
con = ast_context_find(parking_con);
if (con) {
- if (ast_context_remove_extension2(con, pt->parkingexten, 1, NULL))
+ if (ast_context_remove_extension2(con, pt->parkingexten, 1, NULL)) {
ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
- else {
+ } else {
notify_metermaids(pt->parkingexten, parking_con);
}
- } else
+ } else {
ast_log(LOG_WARNING, "Whoa, no parking context?\n");
+ }
free(pt);
break;
} else {
/*! \todo XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
ast_frfree(f);
if (pu->moh_trys < 3 && !chan->generatordata) {
- if (option_debug)
+ if (option_debug) {
ast_log(LOG_DEBUG, "MOH on parked call stopped by outside source. Restarting.\n");
- ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
+ }
+ ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
S_OR(parkmohclass, NULL),
!ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
pu->moh_trys++;
@@ -2441,30 +2468,38 @@
} /* end for */
if (x >= AST_MAX_FDS) {
-std: for (x=0; x<AST_MAX_FDS; x++) { /* mark fds for next round */
+std: for (x = 0; x < AST_MAX_FDS; x++) { /* mark fds for next round */
if (chan->fds[x] > -1) {
- FD_SET(chan->fds[x], &nrfds);
- FD_SET(chan->fds[x], &nefds);
- if (chan->fds[x] > max)
- max = chan->fds[x];
+ void *tmp = ast_realloc(new_fds, (new_nfds + 1) * sizeof(*new_fds));
+ if (!tmp) {
+ continue;
+ }
+ new_fds = tmp;
+ new_fds[new_nfds].fd = chan->fds[x];
+ new_fds[new_nfds].events = POLLIN | POLLERR;
+ new_nfds++;
}
}
/* Keep track of our shortest wait */
- if (tms < ms || ms < 0)
+ if (tms < ms || ms < 0) {
ms = tms;
+ }
pl = pu;
pu = pu->next;
}
}
} /* end while */
ast_mutex_unlock(&parking_lock);
- rfds = nrfds;
- efds = nefds;
- {
- struct timeval tv = ast_samp2tv(ms, 1000);
- /* Wait for something to happen */
- ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &tv : NULL);
- }
+ ast_free(fds);
+ fds = new_fds;
+ nfds = new_nfds;
+ new_fds = NULL;
+ new_nfds = 0;
+
+ tv = ast_samp2tv(ms, 1000);
+ /* Wait for something to happen */
+ ast_poll2(fds, nfds, (ms > -1) ? &tv : NULL);
+
pthread_testcancel();
}
return NULL; /* Never reached */
More information about the asterisk-commits
mailing list