[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