[asterisk-commits] MESSAGE: Flush Message/ast msg queue channel alert pipe. (asterisk[master])
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Dec 20 05:29:35 CST 2016
Joshua Colp has submitted this change and it was merged. ( https://gerrit.asterisk.org/4625 )
Change subject: MESSAGE: Flush Message/ast_msg_queue channel alert pipe.
......................................................................
MESSAGE: Flush Message/ast_msg_queue channel alert pipe.
ASTERISK-25083
Change-Id: Id54baa57a8dbca84e29f28bcd2ffc0a5ac12d8b2
---
M include/asterisk/channel.h
M main/channel_internal_api.c
M main/message.c
3 files changed, 65 insertions(+), 7 deletions(-)
Approvals:
George Joseph: Looks good to me, but someone else must approve
Anonymous Coward #1000019: Verified
Joshua Colp: Looks good to me, approved
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 6f22027..1b7246b 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -4229,6 +4229,7 @@
} ast_alert_status_t;
int ast_channel_alert_write(struct ast_channel *chan);
int ast_channel_alert_writable(struct ast_channel *chan);
+ast_alert_status_t ast_channel_internal_alert_flush(struct ast_channel *chan);
ast_alert_status_t ast_channel_internal_alert_read(struct ast_channel *chan);
int ast_channel_internal_alert_readable(struct ast_channel *chan);
void ast_channel_internal_alertpipe_clear(struct ast_channel *chan);
diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c
index 50f6c5d..691dec0 100644
--- a/main/channel_internal_api.c
+++ b/main/channel_internal_api.c
@@ -1239,14 +1239,9 @@
return write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah);
}
-ast_alert_status_t ast_channel_internal_alert_read(struct ast_channel *chan)
+static int channel_internal_alert_check_nonblock(struct ast_channel *chan)
{
int flags;
- char blah;
-
- if (!ast_channel_internal_alert_readable(chan)) {
- return AST_ALERT_NOT_READABLE;
- }
flags = fcntl(chan->alertpipe[0], F_GETFL);
/* For some odd reason, the alertpipe occasionally loses nonblocking status,
@@ -1255,9 +1250,62 @@
ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", ast_channel_name(chan));
if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
- return AST_ALERT_READ_FATAL;
+ return -1;
}
}
+ return 0;
+}
+
+ast_alert_status_t ast_channel_internal_alert_flush(struct ast_channel *chan)
+{
+ int bytes_read;
+ char blah[100];
+
+ if (!ast_channel_internal_alert_readable(chan)) {
+ return AST_ALERT_NOT_READABLE;
+ }
+ if (channel_internal_alert_check_nonblock(chan)) {
+ return AST_ALERT_READ_FATAL;
+ }
+
+ /* Read the alertpipe until it is exhausted. */
+ for (;;) {
+ bytes_read = read(chan->alertpipe[0], blah, sizeof(blah));
+ if (bytes_read < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ /*
+ * Would block so nothing left to read.
+ * This is the normal loop exit.
+ */
+ break;
+ }
+ ast_log(LOG_WARNING, "read() failed flushing alertpipe: %s\n",
+ strerror(errno));
+ return AST_ALERT_READ_FAIL;
+ }
+ if (!bytes_read) {
+ /* Read nothing so we are done */
+ break;
+ }
+ }
+
+ return AST_ALERT_READ_SUCCESS;
+}
+
+ast_alert_status_t ast_channel_internal_alert_read(struct ast_channel *chan)
+{
+ char blah;
+
+ if (!ast_channel_internal_alert_readable(chan)) {
+ return AST_ALERT_NOT_READABLE;
+ }
+ if (channel_internal_alert_check_nonblock(chan)) {
+ return AST_ALERT_READ_FATAL;
+ }
+
if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) {
if (errno != EINTR && errno != EAGAIN) {
ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
diff --git a/main/message.c b/main/message.c
index a326fb9..a6b0488 100644
--- a/main/message.c
+++ b/main/message.c
@@ -775,11 +775,20 @@
if (msg_ds) {
ast_channel_datastore_add(chan, msg_ds);
}
+
/*
* Clear softhangup flags.
*/
ast_channel_clear_softhangup(chan, AST_SOFTHANGUP_ALL);
+ /*
+ * Flush the alert pipe in case we miscounted somewhere when
+ * messing with frames on the read queue, we had to flush the
+ * read queue above, or we had an "Exceptionally long queue
+ * length" event.
+ */
+ ast_channel_internal_alert_flush(chan);
+
ast_channel_unlock(chan);
}
--
To view, visit https://gerrit.asterisk.org/4625
To unsubscribe, visit https://gerrit.asterisk.org/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Id54baa57a8dbca84e29f28bcd2ffc0a5ac12d8b2
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: Richard Mudgett <rmudgett at digium.com>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
More information about the asterisk-commits
mailing list