diff options
author | Ray Strode <rstrode@redhat.com> | 2013-09-20 15:20:39 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2013-09-20 16:06:02 -0400 |
commit | 29ef8217665fa1cd000e4668e01dbd638ab61f5e (patch) | |
tree | fe345f3af2d0d2c901cf637e2ca8b5691ed4c2ba /tests | |
parent | cb7059e17f48c77eeb2e8354ddb64c149a312262 (diff) |
tests: add signal disconnection test
This commit adds a test to ensure that during a signal emission, if
a signal handler gets disconnected, it won't be run, even if it would
have run before the disconnection.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/gobject/Makefile.am | 2 | ||||
-rw-r--r-- | tests/gobject/signals.c | 135 |
2 files changed, 137 insertions, 0 deletions
diff --git a/tests/gobject/Makefile.am b/tests/gobject/Makefile.am index 152637b95..84f741082 100644 --- a/tests/gobject/Makefile.am +++ b/tests/gobject/Makefile.am @@ -19,6 +19,7 @@ installed_test_programs = \ defaultiface \ dynamictype \ override \ + signals \ singleton \ references \ $(NULL) @@ -39,6 +40,7 @@ TESTS_ENVIRONMENT = \ MALLOC_PERTURB_=$$(($${RANDOM:-256} % 256)) accumulator_SOURCES = accumulator.c testmarshal.c testmarshal.h +signals_SOURCES = signals.c defaultiface_SOURCES = defaultiface.c testmodule.c testmodule.h dynamictype_SOURCES = dynamictype.c testmodule.c testmodule.h diff --git a/tests/gobject/signals.c b/tests/gobject/signals.c new file mode 100644 index 000000000..6f5149c9a --- /dev/null +++ b/tests/gobject/signals.c @@ -0,0 +1,135 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2013 Red Hat, Inc. + * Copy and pasted from accumulator.c and modified. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "TestSignals" + +#undef G_DISABLE_ASSERT +#undef G_DISABLE_CHECKS +#undef G_DISABLE_CAST_CHECKS + +#include <glib-object.h> + +#include "testcommon.h" + +/* What this test tests is the behavior of signal disconnection + * from within a signal handler for the signal being disconnected. + * + * The test demonstrates that signal handlers disconnected from a signal + * from an earlier handler in the same emission will not be run. + * + * It also demonstrates that signal handlers connected from a signal + * from an earlier handler in the same emission will not be run. + */ + +/* + * TestObject, a parent class for TestObject + */ +#define TEST_TYPE_OBJECT (test_object_get_type ()) +typedef struct _TestObject TestObject; +typedef struct _TestObjectClass TestObjectClass; +static gboolean callback1_ran = FALSE, callback2_ran = FALSE, callback3_ran = FALSE, default_handler_ran = FALSE; + +struct _TestObject +{ + GObject parent_instance; +}; +struct _TestObjectClass +{ + GObjectClass parent_class; + + void (*test_signal) (TestObject *object); +}; + +static GType test_object_get_type (void); + +static void +test_object_real_signal (TestObject *object) +{ + default_handler_ran = TRUE; +} + +static void +test_object_signal_callback3 (TestObject *object, + gpointer data) +{ + callback3_ran = TRUE; +} + +static void +test_object_signal_callback2 (TestObject *object, + gpointer data) +{ + callback2_ran = TRUE; +} + +static void +test_object_signal_callback1 (TestObject *object, + gpointer data) +{ + callback1_ran = TRUE; + g_signal_handlers_disconnect_by_func (G_OBJECT (object), + test_object_signal_callback2, + data); + g_signal_connect (object, "test-signal", + G_CALLBACK (test_object_signal_callback3), NULL); +} + +static void +test_object_class_init (TestObjectClass *class) +{ + class->test_signal = test_object_real_signal; + + g_signal_new ("test-signal", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (TestObjectClass, test_signal), + NULL, NULL, NULL, G_TYPE_NONE, 0); +} + +static DEFINE_TYPE(TestObject, test_object, + test_object_class_init, NULL, NULL, + G_TYPE_OBJECT) + +int +main (int argc, + char *argv[]) +{ + TestObject *object; + + g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | + G_LOG_LEVEL_WARNING | + G_LOG_LEVEL_CRITICAL); + + object = g_object_new (TEST_TYPE_OBJECT, NULL); + + g_signal_connect (object, "test-signal", + G_CALLBACK (test_object_signal_callback1), NULL); + g_signal_connect (object, "test-signal", + G_CALLBACK (test_object_signal_callback2), NULL); + g_signal_emit_by_name (object, "test-signal"); + + g_assert (callback1_ran); + g_assert (!callback2_ran); + g_assert (!callback3_ran); + g_assert (default_handler_ran); + + return 0; +} |