diff options
-rw-r--r-- | include/asterisk/linkedlists.h | 10 | ||||
-rw-r--r-- | main/channel.c | 5 |
2 files changed, 11 insertions, 4 deletions
diff --git a/include/asterisk/linkedlists.h b/include/asterisk/linkedlists.h index 2c9a570c1..1bf933a14 100644 --- a/include/asterisk/linkedlists.h +++ b/include/asterisk/linkedlists.h @@ -729,8 +729,10 @@ struct { \ used to link entries of this list together. \warning The removed entry is \b not freed nor modified in any way. */ -#define AST_LIST_REMOVE(head, elm, field) do { \ +#define AST_LIST_REMOVE(head, elm, field) ({ \ + __typeof(elm) __res = NULL; \ if ((head)->first == (elm)) { \ + __res = (head)->first; \ (head)->first = (elm)->field.next; \ if ((head)->last == (elm)) \ (head)->last = NULL; \ @@ -739,13 +741,15 @@ struct { \ while (curelm && (curelm->field.next != (elm))) \ curelm = curelm->field.next; \ if (curelm) { \ + __res = curelm; \ curelm->field.next = (elm)->field.next; \ if ((head)->last == (elm)) \ (head)->last = curelm; \ } \ } \ - (elm)->field.next = NULL; \ -} while (0) + (elm)->field.next = NULL; \ + (__res); \ +}) #define AST_RWLIST_REMOVE AST_LIST_REMOVE diff --git a/main/channel.c b/main/channel.c index d75e98306..c0aa2326e 100644 --- a/main/channel.c +++ b/main/channel.c @@ -1082,7 +1082,10 @@ void ast_channel_free(struct ast_channel *chan) headp=&chan->varshead; AST_LIST_LOCK(&channels); - AST_LIST_REMOVE(&channels, chan, chan_list); + if (!AST_LIST_REMOVE(&channels, chan, chan_list)) { + AST_LIST_UNLOCK(&channels); + ast_log(LOG_ERROR, "Unable to find channel in list to free. Assuming it has already been done.\n"); + } /* Lock and unlock the channel just to be sure nobody has it locked still */ ast_channel_lock(chan); |