g_signal_handlers_block_matched doesn't block



Hi,

this may be (and probably is) a misunderstanding of how block_matched is
supposed to work, but when I tell it to block by signal ID, it doesn't
seem to do anything. Attached is a small program that as far as I
understand it, should try to emit a signal 100 times, but every other
time the signal should be blocked. 

When I compile and run it, I find that the signal handler didn't find
any handlers to block, and so the signal is actually emitted 100 times,
instead of 50.

Is it a bug in g_signal_handlers_block_matched when blocking by signal
id, or am I just stupid and missed something obvious?

iain
[Compile with gcc block-test.c -o block-test `pkg-config --cflags --libs
glib-2.0 gobject-2.0`]
-- 
"I am the clerk, the technician, the mechanic, the driver. They said, Do
this, do that, don't look left or right, don't read the text. Don't look
at the whole machine. You are only responsible for this one bolt, this
one rubber stamp." - Mordechai Vanunu
#include <glib.h>
#include <glib-object.h>

enum {
	TEST_SIGNAL,
	LAST_SIGNAL
};
static guint32 signals[LAST_SIGNAL];

typedef struct _TestObject {
	GObject parent;

	int dummy;
} TestObject;

typedef struct _TestObjectClass {
	GObjectClass parent_class;

	void (*test_signal) (TestObject *object);
} TestObjectClass;

static GObjectClass *parent_class;

static void
class_init (TestObjectClass *class)
{
	parent_class = g_type_class_peek_parent (class);

	signals[TEST_SIGNAL] = g_signal_new ("test-signal",
						G_TYPE_FROM_CLASS (class),
						G_SIGNAL_RUN_FIRST,
						G_STRUCT_OFFSET (TestObjectClass, test_signal),
						NULL, NULL,
						g_cclosure_marshal_VOID__VOID,
						G_TYPE_NONE, 0);
}

static void
test_signal_cb (TestObject *object,
		gpointer data)
{
	object->dummy++;
}

static void
init (TestObject *obj)
{
	g_signal_connect (G_OBJECT (obj), "test-signal",
			  G_CALLBACK (test_signal_cb), NULL);
	obj->dummy = 0;
}

GType 
get_type (void)
{
	static GType type = 0;

	if (type == 0) {
		static GTypeInfo info = {
			sizeof (TestObjectClass), NULL, NULL,
			(GClassInitFunc) class_init, NULL, NULL,
			sizeof (TestObject), 0, (GInstanceInitFunc) init
		};

		type = g_type_register_static (G_TYPE_OBJECT,
						"test-object", &info, 0);
	}

	return type;
}

void
test_object_emit_signal (TestObject *test)
{
	g_signal_emit (G_OBJECT (test), signals[TEST_SIGNAL], 0);
}

int
main (int argc, 
      char **argv)
{
	TestObject *test;
	int i;
	guint signal_id;
	
	g_type_init ();
	g_signal_init ();

	test = g_object_new (get_type (), NULL);

	signal_id = g_signal_lookup ("test-signal", get_type ());
	g_print ("lookup says signal is %d\narray says %d\n", signal_id,
		 signals[TEST_SIGNAL]);
	for (i = 0; i < 100; i++) {
		if (i % 2 == 0) {
			int b;
			
			b = g_signal_handlers_block_matched (G_OBJECT (test),
					G_SIGNAL_MATCH_ID, signal_id,
					0, NULL, NULL, NULL);
			g_print ("blocked %d signals\n", b);
		}

		test_object_emit_signal (test);

		if (i % 2 == 0) {
			g_signal_handlers_unblock_matched (G_OBJECT (test),
					G_SIGNAL_MATCH_ID, signal_id,
					0, NULL, NULL, NULL);
		}
	}

	g_print ("Callback was called %d times\n", test->dummy);
	exit (0);
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]