From 8c8ab2a9ebc1c179df89c2469150a95c917b3248 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Tue, 1 Mar 2016 08:27:13 -0500 Subject: [PATCH] core/idle: Add idle_cancel() function This function is used to cancel all idle tasks and free the memory allocated for them. This needs to be called when Ocarina is shutting down to prevent a possible hang with the gtk idle callback continuing to process tasks. Fixes #30: Closing Ocarina should cancel idle tasks Signed-off-by: Anna Schumaker --- core/idle.c | 10 ++++++++++ gui/ocarina.cpp | 11 ++++++++++- include/core/idle.h | 3 +++ tests/core/idle.c | 7 +++++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/core/idle.c b/core/idle.c index 08b07134..7b3a6a82 100644 --- a/core/idle.c +++ b/core/idle.c @@ -50,3 +50,13 @@ float idle_progress() return 1.0; return serviced / queued; } + +void idle_cancel() +{ + struct idle_task *task; + + while (!g_queue_is_empty(&idle_queue)) { + task = g_queue_pop_head(&idle_queue); + g_free(task); + } +} diff --git a/gui/ocarina.cpp b/gui/ocarina.cpp index d203728b..a71a681f 100644 --- a/gui/ocarina.cpp +++ b/gui/ocarina.cpp @@ -2,6 +2,9 @@ * Copyright 2014 (c) Anna Schumaker. */ #include +extern "C" { +#include +} #include #include @@ -42,6 +45,11 @@ static void setup_share(const std::string &path) ocarina_dir = ocarina_dir + "share/ocarina/"; } +static void on_window_removed(Gtk::Window *window) +{ + idle_cancel(); +} + int main(int argc, char **argv) { Gtk::Window *window; @@ -63,7 +71,8 @@ int main(int argc, char **argv) window = window_init(); post_init_tabs(); - ocarina_app->run(*window); + ocarina_app->signal_window_removed().connect(sigc::ptr_fun(on_window_removed)); + ocarina_app->run(*window, argc, argv); cleanup_tabs(); gst :: quit(); core :: deinit(); diff --git a/include/core/idle.h b/include/core/idle.h index f4cc7067..b9660ea3 100644 --- a/include/core/idle.h +++ b/include/core/idle.h @@ -27,4 +27,7 @@ bool idle_run_task(); /* Called to find the percentage of idle tasks that have been run. */ float idle_progress(); +/* Called to cancel all idle tasks on the queue. */ +void idle_cancel(); + #endif /* OCARINA_CORE_IDLE_H */ diff --git a/tests/core/idle.c b/tests/core/idle.c index c5151025..c7d5d8c7 100644 --- a/tests/core/idle.c +++ b/tests/core/idle.c @@ -36,6 +36,13 @@ static void test_idle_queue(unsigned int n) test_equal(idle_run_task(), (bool)false); test_equal(idle_progress(), (float)1.0); + + for (unsigned int i = 0; i < n; i++) + idle_schedule(inc_cur, GINT_TO_POINTER(i)); + test_equal(idle_progress(), (float)0.0); + + idle_cancel(); + test_equal(idle_progress(), (float)1.0); }