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; | ||||
| 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); | ||||
|   | ||||
| @@ -1239,14 +1239,9 @@ int ast_channel_alert_write(struct ast_channel *chan) | ||||
| 	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_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)); | ||||
| 		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)); | ||||
|   | ||||
| @@ -775,11 +775,20 @@ static void chan_cleanup(struct ast_channel *chan) | ||||
| 	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); | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user