From fe9e0e672e84a80a12a329ab82b1f0fd4a62d053 Mon Sep 17 00:00:00 2001
From: Tilghman Lesher <tilghman@meg.abyt.es>
Date: Fri, 16 Jul 2010 20:35:28 +0000
Subject: [PATCH] Finally, a method that really fixes the assertions in
 chan_iax2.c related to cancelling lagid.

No, replacing usleep(1) with sched_yield() did not have an effect.


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@277484 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 include/asterisk/sched.h | 10 +++++-----
 main/sched.c             | 27 +++++++++++++++++++++------
 2 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/include/asterisk/sched.h b/include/asterisk/sched.h
index 4f5fb42170..3904daf36f 100644
--- a/include/asterisk/sched.h
+++ b/include/asterisk/sched.h
@@ -53,7 +53,7 @@ extern "C" {
 		int _count = 0; \
 		int _sched_res = -1; \
 		while (id > -1 && (_sched_res = ast_sched_del(sched, id)) && ++_count < 10) \
-			usleep(1); \
+			usleep(1000); \
 		if (_count == 10 && option_debug > 2) { \
 			ast_log(LOG_DEBUG, "Unable to cancel schedule ID %d.\n", id); \
 		} \
@@ -70,7 +70,7 @@ extern "C" {
 	do { \
 		int _count = 0; \
 		while (id > -1 && ast_sched_del(sched, id) && ++_count < 10) { \
-			usleep(1); \
+			usleep(1000); \
 		} \
 		if (_count == 10) \
 			ast_log(LOG_WARNING, "Unable to cancel schedule ID %d.  This is probably a bug (%s: %s, line %d).\n", id, __FILE__, __PRETTY_FUNCTION__, __LINE__); \
@@ -89,7 +89,7 @@ extern "C" {
 		int _sched_res = -1; \
 		while (id > -1 && (_sched_res = ast_sched_del(sched, id)) && ++_count < 10) { \
 			ast_mutex_unlock(lock); \
-			usleep(1); \
+			usleep(1000); \
 			ast_mutex_lock(lock); \
 		} \
 		if (_count == 10 && option_debug > 2) { \
@@ -103,7 +103,7 @@ extern "C" {
 	do { \
 		int _count = 0; \
 		while (id > -1 && ast_sched_del(sched, id) && ++_count < 10) { \
-			usleep(1); \
+			usleep(1000); \
 		} \
 		if (_count == 10) \
 			ast_log(LOG_WARNING, "Unable to cancel schedule ID %d.  This is probably a bug (%s: %s, line %d).\n", id, __FILE__, __PRETTY_FUNCTION__, __LINE__); \
@@ -122,7 +122,7 @@ extern "C" {
 		int _count = 0, _res=1;											 \
 		void *_data = (void *)ast_sched_find_data(sched, id);			\
 		while (id > -1 && (_res = ast_sched_del(sched, id) && _count++ < 10)) { \
-			usleep(1); \
+			usleep(1000); \
 		} \
 		if (!_res && _data)							\
 			unrefcall;	/* should ref _data! */		\
diff --git a/main/sched.c b/main/sched.c
index 8699cfbabc..78de1a99e5 100644
--- a/main/sched.c
+++ b/main/sched.c
@@ -46,6 +46,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/dlinkedlists.h"
 #include "asterisk/hashtab.h"
 #include "asterisk/heap.h"
+#include "asterisk/threadstorage.h"
+
+AST_THREADSTORAGE(last_del_id);
 
 struct sched {
 	AST_LIST_ENTRY(sched) list;
@@ -450,7 +453,7 @@ const void *ast_sched_find_data(struct sched_context *con, int id)
 		return res->data;
 	return NULL;
 }
-	
+
 /*! \brief
  * Delete the schedule entry with number
  * "id".  It's nearly impossible that there
@@ -466,9 +469,14 @@ int _ast_sched_del(struct sched_context *con, int id, const char *file, int line
 	struct sched *s, tmp = {
 		.id = id,
 	};
+	int *last_id = ast_threadstorage_get(&last_del_id, sizeof(int *));
 
 	DEBUG(ast_debug(1, "ast_sched_del(%d)\n", id));
-	
+
+	if (id < 0) {
+		return 0;
+	}
+
 	ast_mutex_lock(&con->lock);
 	s = ast_hashtab_lookup(con->schedq_ht, &tmp);
 	if (s) {
@@ -484,7 +492,7 @@ int _ast_sched_del(struct sched_context *con, int id, const char *file, int line
 
 		sched_release(con, s);
 	}
-	
+
 #ifdef DUMP_SCHEDULER
 	/* Dump contents of the context while we have the lock so nothing gets screwed up by accident. */
 	if (option_debug)
@@ -492,16 +500,23 @@ int _ast_sched_del(struct sched_context *con, int id, const char *file, int line
 #endif
 	ast_mutex_unlock(&con->lock);
 
-	if (!s) {
+	if (!s && *last_id != id) {
 		ast_debug(1, "Attempted to delete nonexistent schedule entry %d!\n", id);
 #ifndef AST_DEVMODE
 		ast_assert(s != NULL);
 #else
-		_ast_assert(0, "s != NULL", file, line, function);
+		{
+		char buf[100];
+		snprintf(buf, sizeof(buf), "s != NULL, id=%d", id);
+		_ast_assert(0, buf, file, line, function);
+		}
 #endif
+		*last_id = id;
+		return -1;
+	} else if (!s) {
 		return -1;
 	}
-	
+
 	return 0;
 }
 
-- 
GitLab