mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-25 06:00:36 +00:00 
			
		
		
		
	MESSAGE: Flush Message/ast_msg_queue channel alert pipe.
ASTERISK-25083 Change-Id: Id54baa57a8dbca84e29f28bcd2ffc0a5ac12d8b2
This commit is contained in:
		| @@ -4229,6 +4229,7 @@ typedef enum { | |||||||
| } ast_alert_status_t; | } ast_alert_status_t; | ||||||
| int ast_channel_alert_write(struct ast_channel *chan); | int ast_channel_alert_write(struct ast_channel *chan); | ||||||
| int ast_channel_alert_writable(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); | ast_alert_status_t ast_channel_internal_alert_read(struct ast_channel *chan); | ||||||
| int ast_channel_internal_alert_readable(struct ast_channel *chan); | int ast_channel_internal_alert_readable(struct ast_channel *chan); | ||||||
| void ast_channel_internal_alertpipe_clear(struct ast_channel *chan); | void ast_channel_internal_alertpipe_clear(struct ast_channel *chan); | ||||||
|   | |||||||
| @@ -1239,14 +1239,9 @@ int ast_channel_alert_write(struct ast_channel *chan) | |||||||
| 	return write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah); | 	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; | 	int flags; | ||||||
| 	char blah; |  | ||||||
|  |  | ||||||
| 	if (!ast_channel_internal_alert_readable(chan)) { |  | ||||||
| 		return AST_ALERT_NOT_READABLE; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	flags = fcntl(chan->alertpipe[0], F_GETFL); | 	flags = fcntl(chan->alertpipe[0], F_GETFL); | ||||||
| 	/* For some odd reason, the alertpipe occasionally loses nonblocking status, | 	/* For some odd reason, the alertpipe occasionally loses nonblocking status, | ||||||
| @@ -1255,9 +1250,62 @@ ast_alert_status_t ast_channel_internal_alert_read(struct ast_channel *chan) | |||||||
| 		ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", ast_channel_name(chan)); | 		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) { | 		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)); | 			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 (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) { | ||||||
| 		if (errno != EINTR && errno != EAGAIN) { | 		if (errno != EINTR && errno != EAGAIN) { | ||||||
| 			ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); | 			ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); | ||||||
|   | |||||||
| @@ -775,11 +775,20 @@ static void chan_cleanup(struct ast_channel *chan) | |||||||
| 	if (msg_ds) { | 	if (msg_ds) { | ||||||
| 		ast_channel_datastore_add(chan, msg_ds); | 		ast_channel_datastore_add(chan, msg_ds); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 * Clear softhangup flags. | 	 * Clear softhangup flags. | ||||||
| 	 */ | 	 */ | ||||||
| 	ast_channel_clear_softhangup(chan, AST_SOFTHANGUP_ALL); | 	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); | 	ast_channel_unlock(chan); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user