summaryrefslogtreecommitdiff
path: root/channels/sig_pri.c
diff options
context:
space:
mode:
authorTzafrir Cohen <tzafrir.cohen@xorcom.com>2014-06-23 07:44:19 +0000
committerTzafrir Cohen <tzafrir.cohen@xorcom.com>2014-06-23 07:44:19 +0000
commit3451d6a72d0499a83d82ce03d00d2156a1258c8b (patch)
tree6b3bf6bf6b1c5c5b840d1083cdc92c86f508f1ed /channels/sig_pri.c
parent682357dced7caccaa7e11164bf2e3509acbd8c06 (diff)
suspended destructions of pri spans on events
If a DAHDI span disappears, we wish for its representation in Asterisk to be destroyed as well. The information about the span's removal may come from several paths: 1. DAHDI sends DAHDI_EVENT_REMOVE on every channel. 2. An extra DAHDI_EVENT_REMOVED is sent on every subsequent call to DAHDI_GET_EVENT. 3. Every read (including the internal one by libpri on the D-channel) returns -ENODEV. Asterisk responsds to DAHDI_EVENT_REMOVE on a channel by destroying it. Destroying a channel requires holding the channel list lock (iflock). Destroying a channel that is part of a span requires holding the span's lock. Destroying a channel from a context that holds the span lock, while at the same time another channel is destroyed directly, leads to a deadlock. Solution: don't destroy span while holding the channels list lock. Thus changes in this patch: * Deferring removal of PRI spans in response to events: doomed spans are collected on a list. * Doomed spans are removed periodically by the monitor thread. * ENODEV reads from the D-channel will warant the same deferred removal. Review: https://reviewboard.asterisk.org/r/3548/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@417059 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/sig_pri.c')
-rw-r--r--channels/sig_pri.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/channels/sig_pri.c b/channels/sig_pri.c
index 57c518c88..4c1f170f1 100644
--- a/channels/sig_pri.c
+++ b/channels/sig_pri.c
@@ -1452,6 +1452,27 @@ static int pri_find_principle_by_call(struct sig_pri_span *pri, q931_call *call)
/*!
* \internal
+ * \brief Queue the span for destruction
+ * \since 13.0
+ *
+ * \param pri PRI span control structure.
+ *
+ * Asks the channel driver to queue the span for destruction at a
+ * possibly later time, if (e.g.) locking considerations don't allow
+ * destroying it right now.
+ *
+ * \return Nothing
+ */
+static void pri_destroy_later(struct sig_pri_span *pri)
+{
+ if (!sig_pri_callbacks.destroy_later) {
+ return;
+ }
+ sig_pri_callbacks.destroy_later(pri);
+}
+
+/*!
+ * \internal
* \brief Kill the call.
* \since 10.0
*
@@ -6427,6 +6448,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) {
+ pri_destroy_later(pri);
+ }
}
} else if (errno != EINTR)
ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));