[Pkg-voip-commits] [asterisk] 01/01: fix regressions due to dahdi_pri_event_removed
tzafrir at debian.org
tzafrir at debian.org
Mon May 19 15:11:16 UTC 2014
This is an automated email from the git hooks/post-receive script.
tzafrir pushed a commit to branch master
in repository asterisk.
commit 38e5ad0811644d081862c3a2d7a60710e5d89833
Author: Tzafrir Cohen <tzafrir at debian.org>
Date: Mon May 19 17:51:07 2014 +0300
fix regressions due to dahdi_pri_event_removed
pri_destroy_span_prilist.patch, sigpri_handle_enodev_1.patch:
fix regressions due to dahdi_pri_event_removed.
---
debian/changelog | 4 +
debian/patches/pri_destroy_span_prilist.patch | 136 ++++++++++++++++++++++++++
debian/patches/series | 2 +
debian/patches/sigpri_handle_enodev_1.patch | 77 +++++++++++++++
4 files changed, 219 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index ef26d48..988ed25 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -12,6 +12,10 @@ asterisk (1:11.9.0~dfsg-1) UNRELEASED; urgency=medium
[ Daniel Pocock ]
* Make init script more adaptable for multiple instances.
+ [ Tzafrir Cohen ]
+ * pri_destroy_span_prilist.patch, sigpri_handle_enodev_1.patch: fix
+ regressions due to dahdi_pri_event_removed.
+
-- Jeremy Lainé <jeremy.laine at m4x.org> Mon, 19 May 2014 09:38:36 +0200
asterisk (1:11.8.1~dfsg-1) unstable; urgency=high
diff --git a/debian/patches/pri_destroy_span_prilist.patch b/debian/patches/pri_destroy_span_prilist.patch
new file mode 100644
index 0000000..66b171d
--- /dev/null
+++ b/debian/patches/pri_destroy_span_prilist.patch
@@ -0,0 +1,136 @@
+From: Tzafrir Cohen <tzafrir.cohen at xorcom.com>
+Subject: defer destructions of pri spans
+Bug: https://issues.asterisk.org/jira/browse/ASTERISK-23554
+
+Fixes a deadlock in destruction of PRI spans
+
+See also: https://reviewboard.asterisk.org/r/3548
+
+---
+ channels/chan_dahdi.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 files changed, 79 insertions(+), 3 deletions(-)
+
+diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
+index fd5abe2..c21d593 100644
+--- a/channels/chan_dahdi.c
++++ b/channels/chan_dahdi.c
+@@ -1353,6 +1353,14 @@ static struct dahdi_pvt *iflist = NULL; /*!< Main interface list start */
+ static struct dahdi_pvt *ifend = NULL; /*!< Main interface list end */
+
+ #if defined(HAVE_PRI)
++struct doomed_pri {
++ struct sig_pri_span *pri;
++ AST_LIST_ENTRY(doomed_pri) list;
++};
++static AST_LIST_HEAD_STATIC(doomed_pris, doomed_pri);
++
++static void pri_destroy_span(struct sig_pri_span *pri);
++
+ static struct dahdi_parms_pseudo {
+ int buf_no; /*!< Number of buffers */
+ int buf_policy; /*!< Buffer policy */
+@@ -1754,6 +1762,75 @@ static int analogsub_to_dahdisub(enum analog_sub analogsub)
+ return index;
+ }
+
++/*!
++ * \internal
++ * \brief release all members on the doomed pris list
++ * \since 13.0
++ *
++ * Called priodically by the monitor threads to release spans marked for
++ * removal.
++ */
++static void release_doomed_pris(void) {
++#ifdef HAVE_PRI
++ struct doomed_pri *entry;
++ AST_LIST_HEAD_NOLOCK(doomed_pris, doomed_pri) doomed_list;
++
++ /* Move the global list to our local list. This prevents deadlocks with
++ * any pri->lock.
++ */
++ AST_LIST_LOCK(&doomed_pris);
++ doomed_list.first = doomed_pris.first;
++ doomed_list.last = doomed_pris.last;
++ doomed_pris.first = doomed_pris.last = NULL;
++ AST_LIST_UNLOCK(&doomed_pris);
++
++ AST_LIST_TRAVERSE_SAFE_BEGIN(&doomed_list, entry, list) {
++ AST_LIST_REMOVE_CURRENT(list);
++ pri_destroy_span(entry->pri);
++ ast_free(entry);
++ }
++ AST_LIST_TRAVERSE_SAFE_END;
++#endif
++}
++
++#ifdef HAVE_PRI
++/*!
++ * \internal
++ * \brief Queue a span for destruction
++ * \since 13.0
++ *
++ * \param pri the span to destroy
++ *
++ * Add a span to the list of spans to be destroyed later on
++ * by the monitor thread. Allows destroying a span while holding its
++ * lock.
++ */
++static void pri_queue_for_destruction(struct sig_pri_span *pri) {
++ struct doomed_pri *entry;
++ int len = 0;
++
++ AST_LIST_LOCK(&doomed_pris);
++ AST_LIST_TRAVERSE(&doomed_pris, entry, list) {
++ if (entry->pri == pri) {
++ AST_LIST_UNLOCK(&doomed_pris);
++ return;
++ }
++ len++;
++ }
++ entry = ast_calloc(sizeof(struct doomed_pri), 1);
++ if (!entry) {
++ /* Nothing useful to do here. Panic? */
++ ast_log(LOG_WARNING, "Failed allocating memory for a doomed_pri.\n");
++ AST_LIST_UNLOCK(&doomed_pris);
++ return;
++ }
++ entry->pri = pri;
++ ast_debug(4, "Queue span %d for destruction.\n", pri->span);
++ AST_LIST_INSERT_TAIL(&doomed_pris, entry, list);
++ AST_LIST_UNLOCK(&doomed_pris);
++}
++#endif
++
+ static enum analog_event dahdievent_to_analogevent(int event);
+ static int bump_gains(struct dahdi_pvt *p);
+ static int dahdi_setlinear(int dfd, int linear);
+@@ -3229,8 +3306,6 @@ static int sig_pri_tone_to_dahditone(enum sig_pri_tone tone)
+ #endif /* defined(HAVE_PRI) */
+
+ #if defined(HAVE_PRI)
+-static void pri_destroy_span(struct sig_pri_span *pri);
+-
+ static void my_handle_dchan_exception(struct sig_pri_span *pri, int index)
+ {
+ int x;
+@@ -3259,7 +3334,7 @@ static void my_handle_dchan_exception(struct sig_pri_span *pri, int index)
+ pri_event_noalarm(pri, index, 0);
+ break;
+ case DAHDI_EVENT_REMOVED:
+- pri_destroy_span(pri);
++ pri_queue_for_destruction(pri);
+ break;
+ default:
+ break;
+@@ -12172,6 +12247,7 @@ static void *do_monitor(void *data)
+ dahdi_destroy_channel_range(doomed->channel, doomed->channel);
+ doomed = NULL;
+ }
++ release_doomed_pris();
+ if (!i) {
+ break;
+ }
+--
+1.7.1
+
diff --git a/debian/patches/series b/debian/patches/series
index 5f944e4..dcc6fc3 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -25,6 +25,8 @@ pjproject
# Backport of dynamic generation of DAHDI channels:
dahdi_create_channels
+pri_destroy_span_prilist.patch
+sigpri_handle_enodev_1.patch
reenable
ignore_failed_channels.patch
diff --git a/debian/patches/sigpri_handle_enodev_1.patch b/debian/patches/sigpri_handle_enodev_1.patch
new file mode 100644
index 0000000..3ee4789
--- /dev/null
+++ b/debian/patches/sigpri_handle_enodev_1.patch
@@ -0,0 +1,77 @@
+From: Tzafrir Cohen <tzafrir.cohen at xorcom.com
+Subject: handle ENODEV on sig_pri
+Bug: https://issues.asterisk.org/jira/browse/ASTERISK-23554
+
+Handle ENODEV error in libpri following a device removal.
+
+See also: https://reviewboard.asterisk.org/r/3548
+
+---
+ channels/chan_dahdi.c | 3 ++-
+ channels/sig_pri.c | 8 ++++++++
+ channels/sig_pri.h | 2 ++
+ 3 files changed, 12 insertions(+), 1 deletions(-)
+
+diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
+index c21d593..b6b644f 100644
+--- a/channels/chan_dahdi.c
++++ b/channels/chan_dahdi.c
+@@ -1795,7 +1795,6 @@ static void release_doomed_pris(void) {
+
+ #ifdef HAVE_PRI
+ /*!
+- * \internal
+ * \brief Queue a span for destruction
+ * \since 13.0
+ *
+@@ -3617,6 +3616,7 @@ struct sig_pri_callback sig_pri_callbacks =
+ .dial_digits = my_pri_dial_digits,
+ .open_media = my_pri_ss7_open_media,
+ .ami_channel_event = my_ami_channel_event,
++ .destroy_later = pri_queue_for_destruction,
+ };
+ #endif /* defined(HAVE_PRI) */
+
+@@ -15146,6 +15146,7 @@ static void pri_destroy_span(struct sig_pri_span *pri)
+ for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
+ ast_debug(4, "closing pri_fd %d\n", i);
+ dahdi_close_pri_fd(dahdi_pri, i);
++ dahdi_pri->dchannels[i] = 0;
+ }
+ sig_pri_init_pri(pri);
+ ast_debug(1, "PRI span %d destroyed\n", pri->span);
+diff --git a/channels/sig_pri.c b/channels/sig_pri.c
+index 1d9067a..5636594 100644
+--- a/channels/sig_pri.c
++++ b/channels/sig_pri.c
+@@ -6301,6 +6301,14 @@ static void *pri_dchannel(void *vpri)
+ }
+ if (e)
+ break;
++
++ if ((errno != 0) && (errno != EINTR)) {
++ ast_log(LOG_NOTICE, "pri_check_event returned error %d (%s)\n",
++ errno, strerror(errno));
++ }
++ if (errno == ENODEV) {
++ sig_pri_callbacks.destroy_later(pri);
++ }
+ }
+ } else if (errno != EINTR)
+ ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));
+diff --git a/channels/sig_pri.h b/channels/sig_pri.h
+index 43acb12..7bfbc79 100644
+--- a/channels/sig_pri.h
++++ b/channels/sig_pri.h
+@@ -229,6 +229,8 @@ struct sig_pri_callback {
+ void (*module_ref)(void);
+ /*! Unreference the parent module. */
+ void (*module_unref)(void);
++ /*! Mark the span for destruction. */
++ void (*destroy_later)(struct sig_pri_span *pri);
+ };
+
+ /*! Global sig_pri callbacks to the upper layer. */
+--
+1.7.1
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/asterisk.git
More information about the Pkg-voip-commits
mailing list