Message ID | 1443812991-17356-40-git-send-email-marcandre.lureau@redhat.com |
---|---|
State | New |
Headers | show |
On 02.10.2015 21:09, marcandre.lureau@redhat.com wrote: > From: Marc-André Lureau <marcandre.lureau@redhat.com> > > Allow a test to add abort handlers, use GHook for all handlers. > > There is currently no way to remove a handler, but it could be > later added if needed. > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com> > --- > tests/libqtest.c | 37 ++++++++++++++++++++++++------------- > tests/libqtest.h | 2 ++ > 2 files changed, 26 insertions(+), 13 deletions(-) > > diff --git a/tests/libqtest.c b/tests/libqtest.c > index e5188e0..4a3a6ad 100644 > --- a/tests/libqtest.c > +++ b/tests/libqtest.c > @@ -49,6 +49,7 @@ struct QTestState > struct sigaction sigact_old; /* restored on exit */ > }; > > +static GHookList abrt_hooks; > static GList *qtest_instances; > static struct sigaction sigact_old; > > @@ -112,10 +113,7 @@ static void kill_qemu(QTestState *s) > > static void sigabrt_handler(int signo) > { > - GList *elem; > - for (elem = qtest_instances; elem; elem = elem->next) { > - kill_qemu(elem->data); > - } > + g_hook_list_invoke(&abrt_hooks, FALSE); > } > > static void setup_sigabrt_handler(void) > @@ -136,6 +134,23 @@ static void cleanup_sigabrt_handler(void) > sigaction(SIGABRT, &sigact_old, NULL); > } > > +void qtest_add_abrt_handler(void (*fn), const void *data) > +{ > + GHook *hook; > + > + /* Only install SIGABRT handler once */ > + if (!abrt_hooks.is_setup) { > + g_hook_list_init(&abrt_hooks, sizeof(GHook)); > + setup_sigabrt_handler(); > + } > + > + hook = g_hook_alloc(&abrt_hooks); > + hook->func = fn; > + hook->data = (void *)data; > + > + g_hook_prepend(&abrt_hooks, hook); > +} > + > QTestState *qtest_init(const char *extra_args) > { > QTestState *s; > @@ -156,12 +171,7 @@ QTestState *qtest_init(const char *extra_args) > sock = init_socket(socket_path); > qmpsock = init_socket(qmp_socket_path); > > - /* Only install SIGABRT handler once */ > - if (!qtest_instances) { > - setup_sigabrt_handler(); > - } > - > - qtest_instances = g_list_prepend(qtest_instances, s); > + qtest_add_abrt_handler(kill_qemu, s); > > s->qemu_pid = fork(); > if (s->qemu_pid == 0) { > @@ -209,13 +219,14 @@ QTestState *qtest_init(const char *extra_args) > > void qtest_quit(QTestState *s) > { > + qtest_instances = g_list_remove(qtest_instances, s); > + g_hook_destroy_link(&abrt_hooks, g_hook_find_data(&abrt_hooks, TRUE, s)); > + > /* Uninstall SIGABRT handler on last instance */ > - if (qtest_instances && !qtest_instances->next) { > + if (!qtest_instances) { > cleanup_sigabrt_handler(); > } > > - qtest_instances = g_list_remove(qtest_instances, s); > - > kill_qemu(s); > close(s->fd); > close(s->qmp_fd); > diff --git a/tests/libqtest.h b/tests/libqtest.h > index ec42031..f02c07c 100644 > --- a/tests/libqtest.h > +++ b/tests/libqtest.h > @@ -427,6 +427,8 @@ void qtest_add_data_func(const char *str, const void *data, void (*fn)); > g_free(path); \ > } while (0) > > +void qtest_add_abrt_handler(void (*fn), const void *data); > + > /** > * qtest_start: > * @args: other arguments to pass to QEMU >
diff --git a/tests/libqtest.c b/tests/libqtest.c index e5188e0..4a3a6ad 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -49,6 +49,7 @@ struct QTestState struct sigaction sigact_old; /* restored on exit */ }; +static GHookList abrt_hooks; static GList *qtest_instances; static struct sigaction sigact_old; @@ -112,10 +113,7 @@ static void kill_qemu(QTestState *s) static void sigabrt_handler(int signo) { - GList *elem; - for (elem = qtest_instances; elem; elem = elem->next) { - kill_qemu(elem->data); - } + g_hook_list_invoke(&abrt_hooks, FALSE); } static void setup_sigabrt_handler(void) @@ -136,6 +134,23 @@ static void cleanup_sigabrt_handler(void) sigaction(SIGABRT, &sigact_old, NULL); } +void qtest_add_abrt_handler(void (*fn), const void *data) +{ + GHook *hook; + + /* Only install SIGABRT handler once */ + if (!abrt_hooks.is_setup) { + g_hook_list_init(&abrt_hooks, sizeof(GHook)); + setup_sigabrt_handler(); + } + + hook = g_hook_alloc(&abrt_hooks); + hook->func = fn; + hook->data = (void *)data; + + g_hook_prepend(&abrt_hooks, hook); +} + QTestState *qtest_init(const char *extra_args) { QTestState *s; @@ -156,12 +171,7 @@ QTestState *qtest_init(const char *extra_args) sock = init_socket(socket_path); qmpsock = init_socket(qmp_socket_path); - /* Only install SIGABRT handler once */ - if (!qtest_instances) { - setup_sigabrt_handler(); - } - - qtest_instances = g_list_prepend(qtest_instances, s); + qtest_add_abrt_handler(kill_qemu, s); s->qemu_pid = fork(); if (s->qemu_pid == 0) { @@ -209,13 +219,14 @@ QTestState *qtest_init(const char *extra_args) void qtest_quit(QTestState *s) { + qtest_instances = g_list_remove(qtest_instances, s); + g_hook_destroy_link(&abrt_hooks, g_hook_find_data(&abrt_hooks, TRUE, s)); + /* Uninstall SIGABRT handler on last instance */ - if (qtest_instances && !qtest_instances->next) { + if (!qtest_instances) { cleanup_sigabrt_handler(); } - qtest_instances = g_list_remove(qtest_instances, s); - kill_qemu(s); close(s->fd); close(s->qmp_fd); diff --git a/tests/libqtest.h b/tests/libqtest.h index ec42031..f02c07c 100644 --- a/tests/libqtest.h +++ b/tests/libqtest.h @@ -427,6 +427,8 @@ void qtest_add_data_func(const char *str, const void *data, void (*fn)); g_free(path); \ } while (0) +void qtest_add_abrt_handler(void (*fn), const void *data); + /** * qtest_start: * @args: other arguments to pass to QEMU