summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorey Farrell <git@cfware.com>2015-02-19 02:03:01 +0000
committerCorey Farrell <git@cfware.com>2015-02-19 02:03:01 +0000
commita4774ceaa5cc28d6b885270ffa5fa6400e12b474 (patch)
tree40bbf5dead60c99162defeb7a5a6d7464d9c0e81
parent09bfe4b2088e61a085004f5cd679040532533054 (diff)
Create work around for scheduler leaks during shutdown.
* Added ast_sched_clean_by_callback for cleanup of scheduled events that have not yet fired. * Run all pending peercnt_remove_cb and replace_callno events in chan_iax2. Cleanup of replace_callno events is only run 11, since it no longer releases any references or allocations in 13+. ASTERISK-24451 #close Reported by: Corey Farrell Review: https://reviewboard.asterisk.org/r/4425/ ........ Merged revisions 431916 from http://svn.asterisk.org/svn/asterisk/branches/11 ........ Merged revisions 431917 from http://svn.asterisk.org/svn/asterisk/branches/13 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@431918 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--channels/chan_iax2.c4
-rw-r--r--include/asterisk/sched.h11
-rw-r--r--main/sched.c20
3 files changed, 34 insertions, 1 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index b0c426fe1..dbc1bb05c 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -14692,7 +14692,6 @@ static int __unload_module(void)
ao2_ref(users, -1);
ao2_ref(iax_peercallno_pvts, -1);
ao2_ref(iax_transfercallno_pvts, -1);
- ao2_ref(peercnts, -1);
ao2_ref(callno_limits, -1);
ao2_ref(calltoken_ignores, -1);
if (timer) {
@@ -14700,8 +14699,11 @@ static int __unload_module(void)
timer = NULL;
}
transmit_processor = ast_taskprocessor_unreference(transmit_processor);
+
+ ast_sched_clean_by_callback(sched, peercnt_remove_cb, peercnt_remove_cb);
ast_sched_context_destroy(sched);
sched = NULL;
+ ao2_ref(peercnts, -1);
con = ast_context_find(regcontext);
if (con)
diff --git a/include/asterisk/sched.h b/include/asterisk/sched.h
index 67dbf21ce..b775095ad 100644
--- a/include/asterisk/sched.h
+++ b/include/asterisk/sched.h
@@ -170,6 +170,17 @@ void ast_sched_context_destroy(struct ast_sched_context *c);
typedef int (*ast_sched_cb)(const void *data);
#define AST_SCHED_CB(a) ((ast_sched_cb)(a))
+/*!
+ * \brief Clean all scheduled events with matching callback.
+ *
+ * \param con Scheduler Context
+ * \param match Callback to match
+ * \param cleanup_cb Callback to run
+ *
+ * \note The return of cleanup_cb is ignored. No events are rescheduled.
+ */
+void ast_sched_clean_by_callback(struct ast_sched_context *con, ast_sched_cb match, ast_sched_cb cleanup_cb);
+
struct ast_cb_names {
int numassocs;
char *list[10];
diff --git a/main/sched.c b/main/sched.c
index 34f8d5369..8fdbfed36 100644
--- a/main/sched.c
+++ b/main/sched.c
@@ -289,6 +289,26 @@ static void sched_release(struct ast_sched_context *con, struct sched *tmp)
sched_free(tmp);
}
+void ast_sched_clean_by_callback(struct ast_sched_context *con, ast_sched_cb match, ast_sched_cb cleanup_cb)
+{
+ int i = 1;
+ struct sched *current;
+
+ ast_mutex_lock(&con->lock);
+ while ((current = ast_heap_peek(con->sched_heap, i))) {
+ if (current->callback != match) {
+ i++;
+ continue;
+ }
+
+ ast_heap_remove(con->sched_heap, current);
+
+ cleanup_cb(current->data);
+ sched_release(con, current);
+ }
+ ast_mutex_unlock(&con->lock);
+}
+
/*! \brief
* Return the number of milliseconds
* until the next scheduled event