testsuite/threads/: Added a bunch of testcases that show threadsafety bugs in glib.
authorWim Taymans <wim.taymans@gmail.com>
Mon, 29 Nov 2004 14:27:04 +0000 (14:27 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Mon, 29 Nov 2004 14:27:04 +0000 (14:27 +0000)
Original commit message from CVS:
* testsuite/threads/Makefile.am:
* testsuite/threads/signals.c: (gst_test_get_type),
(gst_test_class_init), (gst_test_init), (gst_test_dispose),
(gst_test_set_property), (gst_test_get_property),
(gst_test_do_signal1), (signal2_handler), (gst_test_do_signal2),
(gst_test_do_prop), (run_thread), (main):
Added a bunch of testcases that show threadsafety bugs in glib.

ChangeLog
tests/old/testsuite/threads/Makefile.am
tests/old/testsuite/threads/signals.c [new file with mode: 0644]
testsuite/threads/Makefile.am
testsuite/threads/signals.c [new file with mode: 0644]

index e7c0e9b..3ab02d8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2004-11-29  Wim Taymans  <wim@fluendo.com>
+
+       * testsuite/threads/Makefile.am:
+       * testsuite/threads/signals.c: (gst_test_get_type),
+       (gst_test_class_init), (gst_test_init), (gst_test_dispose),
+       (gst_test_set_property), (gst_test_get_property),
+       (gst_test_do_signal1), (signal2_handler), (gst_test_do_signal2),
+       (gst_test_do_prop), (run_thread), (main):
+       Added a bunch of testcases that show threadsafety bugs in glib.
+
 2004-11-29  Stefan Kost  <ensonic@users.sf.net>
 
        * docs/manual/programs.xml:
index 0c246a2..906dde2 100644 (file)
@@ -1,7 +1,7 @@
 include ../Rules
 
-tests_pass = thread1 thread2 thread3 thread4 thread5 threade threadf 
-tests_fail = 159566
+tests_pass = thread1 thread2 thread3 thread4 thread5 threade threadf signal1
+tests_fail = 159566 signal2 signal3
 
 # threadh
 
@@ -17,3 +17,10 @@ thread4_SOURCES = thread.c
 thread4_CFLAGS = -DTESTNUM=4 $(AM_CFLAGS)
 thread5_SOURCES = thread.c
 thread5_CFLAGS = -DTESTNUM=5 $(AM_CFLAGS)
+
+signal1_SOURCES = signals.c
+signal1_CFLAGS = -DTESTNUM=1 $(AM_CFLAGS)
+signal2_SOURCES = signals.c
+signal2_CFLAGS = -DTESTNUM=2 $(AM_CFLAGS)
+signal3_SOURCES = signals.c
+signal3_CFLAGS = -DTESTNUM=3 $(AM_CFLAGS)
diff --git a/tests/old/testsuite/threads/signals.c b/tests/old/testsuite/threads/signals.c
new file mode 100644 (file)
index 0000000..8fc0cd3
--- /dev/null
@@ -0,0 +1,229 @@
+#include <unistd.h>
+#include <gst/gst.h>
+
+#define GST_TYPE_TEST               (gst_test_get_type ())
+#define GST_TEST(test)              (G_TYPE_CHECK_INSTANCE_CAST ((test), GST_TYPE_TEST, GstTest))
+#define GST_IS_TEST(test)           (G_TYPE_CHECK_INSTANCE_TYPE ((test), GST_TYPE_TEST))
+#define GST_TEST_CLASS(tclass)      (G_TYPE_CHECK_CLASS_CAST ((tclass), GST_TYPE_TEST, GstTestClass))
+#define GST_IS_TEST_CLASS(tclass)   (G_TYPE_CHECK_CLASS_TYPE ((tclass), GST_TYPE_TEST))
+#define GST_TEST_GET_CLASS(test)    (G_TYPE_INSTANCE_GET_CLASS ((test), GST_TYPE_TEST, GstTestClass))
+
+typedef struct _GstTest GstTest;
+typedef struct _GstTestClass GstTestClass;
+
+struct _GstTest
+{
+  GstObject object;
+};
+
+struct _GstTestClass
+{
+  GstObjectClass parent_class;
+
+  void (*test_signal1) (GstTest * test, gint an_int);
+  void (*test_signal2) (GstTest * test, gint an_int);
+};
+
+static GType gst_test_get_type (void);
+
+/* Element signals and args */
+enum
+{
+  TEST_SIGNAL1,
+  TEST_SIGNAL2,
+  /* add more above */
+  LAST_SIGNAL
+};
+
+enum
+{
+  ARG_0,
+  ARG_TEST_PROP
+};
+
+static void gst_test_class_init (GstTestClass * klass);
+static void gst_test_init (GstTest * test);
+static void gst_test_dispose (GObject * object);
+
+static void signal2_handler (GstTest * test, gint anint);
+
+static void gst_test_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_test_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+static GstObjectClass *parent_class = NULL;
+
+static guint gst_test_signals[LAST_SIGNAL] = { 0 };
+
+static GType
+gst_test_get_type (void)
+{
+  static GType test_type = 0;
+
+  if (!test_type) {
+    static const GTypeInfo test_info = {
+      sizeof (GstTestClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) gst_test_class_init,
+      NULL,
+      NULL,
+      sizeof (GstTest),
+      0,
+      (GInstanceInitFunc) gst_test_init,
+      NULL
+    };
+
+    test_type = g_type_register_static (GST_TYPE_OBJECT, "GstTest",
+        &test_info, 0);
+  }
+  return test_type;
+}
+
+static void
+gst_test_class_init (GstTestClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstObjectClass *gstobject_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstobject_class = (GstObjectClass *) klass;
+
+  parent_class = g_type_class_ref (GST_TYPE_OBJECT);
+
+  if (!g_thread_supported ())
+    g_thread_init (NULL);
+
+  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_test_dispose);
+  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_test_set_property);
+  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_test_get_property);
+
+  gst_test_signals[TEST_SIGNAL1] =
+      g_signal_new ("test-signal1", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstTestClass, test_signal1), NULL,
+      NULL, gst_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
+  gst_test_signals[TEST_SIGNAL2] =
+      g_signal_new ("test-signal2", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstTestClass, test_signal2), NULL,
+      NULL, gst_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TEST_PROP,
+      g_param_spec_int ("test-prop", "Test Prop", "Test property",
+          0, 1, 0, G_PARAM_READWRITE));
+
+  klass->test_signal2 = signal2_handler;
+}
+
+static void
+gst_test_init (GstTest * test)
+{
+}
+
+static void
+gst_test_dispose (GObject * object)
+{
+  GstTest *test;
+
+  test = GST_TEST (object);
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gst_test_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstTest *test;
+
+  test = GST_TEST (object);
+
+  switch (prop_id) {
+    case ARG_TEST_PROP:
+      g_value_get_int (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_test_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GstTest *test;
+
+  test = GST_TEST (object);
+
+  switch (prop_id) {
+    case ARG_TEST_PROP:
+      g_value_set_int (value, 0);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_test_do_signal1 (GstTest * test)
+{
+  g_signal_emit (G_OBJECT (test), gst_test_signals[TEST_SIGNAL1], 0, 0);
+}
+
+static void
+signal2_handler (GstTest * test, gint anint)
+{
+}
+
+static void
+gst_test_do_signal2 (GstTest * test)
+{
+  g_signal_emit (G_OBJECT (test), gst_test_signals[TEST_SIGNAL2], 0, 0);
+}
+
+static void
+gst_test_do_prop (GstTest * test)
+{
+  g_object_notify (G_OBJECT (test), "test-prop");
+}
+
+static gpointer
+run_thread (GstTest * test)
+{
+  gint i = 0;
+
+  while (TRUE) {
+    if (TESTNUM == 1)
+      gst_test_do_signal1 (test);
+    if (TESTNUM == 2)
+      gst_test_do_signal2 (test);
+    if (TESTNUM == 3)
+      gst_test_do_prop (test);
+    if ((i++ % 10000) == 0)
+      g_print (".");
+  }
+
+  return NULL;
+}
+
+int
+main (int argc, char **argv)
+{
+  gint i;
+  GstTest *test1, *test2;
+
+  gst_init (&argc, &argv);
+
+  test1 = g_object_new (GST_TYPE_TEST, NULL);
+  test2 = g_object_new (GST_TYPE_TEST, NULL);
+
+  for (i = 0; i < 100; i++) {
+    g_thread_create ((GThreadFunc) run_thread, test1, TRUE, NULL);
+    g_thread_create ((GThreadFunc) run_thread, test2, TRUE, NULL);
+  }
+  sleep (5);
+
+  return 0;
+}
index 0c246a2..906dde2 100644 (file)
@@ -1,7 +1,7 @@
 include ../Rules
 
-tests_pass = thread1 thread2 thread3 thread4 thread5 threade threadf 
-tests_fail = 159566
+tests_pass = thread1 thread2 thread3 thread4 thread5 threade threadf signal1
+tests_fail = 159566 signal2 signal3
 
 # threadh
 
@@ -17,3 +17,10 @@ thread4_SOURCES = thread.c
 thread4_CFLAGS = -DTESTNUM=4 $(AM_CFLAGS)
 thread5_SOURCES = thread.c
 thread5_CFLAGS = -DTESTNUM=5 $(AM_CFLAGS)
+
+signal1_SOURCES = signals.c
+signal1_CFLAGS = -DTESTNUM=1 $(AM_CFLAGS)
+signal2_SOURCES = signals.c
+signal2_CFLAGS = -DTESTNUM=2 $(AM_CFLAGS)
+signal3_SOURCES = signals.c
+signal3_CFLAGS = -DTESTNUM=3 $(AM_CFLAGS)
diff --git a/testsuite/threads/signals.c b/testsuite/threads/signals.c
new file mode 100644 (file)
index 0000000..8fc0cd3
--- /dev/null
@@ -0,0 +1,229 @@
+#include <unistd.h>
+#include <gst/gst.h>
+
+#define GST_TYPE_TEST               (gst_test_get_type ())
+#define GST_TEST(test)              (G_TYPE_CHECK_INSTANCE_CAST ((test), GST_TYPE_TEST, GstTest))
+#define GST_IS_TEST(test)           (G_TYPE_CHECK_INSTANCE_TYPE ((test), GST_TYPE_TEST))
+#define GST_TEST_CLASS(tclass)      (G_TYPE_CHECK_CLASS_CAST ((tclass), GST_TYPE_TEST, GstTestClass))
+#define GST_IS_TEST_CLASS(tclass)   (G_TYPE_CHECK_CLASS_TYPE ((tclass), GST_TYPE_TEST))
+#define GST_TEST_GET_CLASS(test)    (G_TYPE_INSTANCE_GET_CLASS ((test), GST_TYPE_TEST, GstTestClass))
+
+typedef struct _GstTest GstTest;
+typedef struct _GstTestClass GstTestClass;
+
+struct _GstTest
+{
+  GstObject object;
+};
+
+struct _GstTestClass
+{
+  GstObjectClass parent_class;
+
+  void (*test_signal1) (GstTest * test, gint an_int);
+  void (*test_signal2) (GstTest * test, gint an_int);
+};
+
+static GType gst_test_get_type (void);
+
+/* Element signals and args */
+enum
+{
+  TEST_SIGNAL1,
+  TEST_SIGNAL2,
+  /* add more above */
+  LAST_SIGNAL
+};
+
+enum
+{
+  ARG_0,
+  ARG_TEST_PROP
+};
+
+static void gst_test_class_init (GstTestClass * klass);
+static void gst_test_init (GstTest * test);
+static void gst_test_dispose (GObject * object);
+
+static void signal2_handler (GstTest * test, gint anint);
+
+static void gst_test_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_test_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+static GstObjectClass *parent_class = NULL;
+
+static guint gst_test_signals[LAST_SIGNAL] = { 0 };
+
+static GType
+gst_test_get_type (void)
+{
+  static GType test_type = 0;
+
+  if (!test_type) {
+    static const GTypeInfo test_info = {
+      sizeof (GstTestClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) gst_test_class_init,
+      NULL,
+      NULL,
+      sizeof (GstTest),
+      0,
+      (GInstanceInitFunc) gst_test_init,
+      NULL
+    };
+
+    test_type = g_type_register_static (GST_TYPE_OBJECT, "GstTest",
+        &test_info, 0);
+  }
+  return test_type;
+}
+
+static void
+gst_test_class_init (GstTestClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstObjectClass *gstobject_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstobject_class = (GstObjectClass *) klass;
+
+  parent_class = g_type_class_ref (GST_TYPE_OBJECT);
+
+  if (!g_thread_supported ())
+    g_thread_init (NULL);
+
+  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_test_dispose);
+  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_test_set_property);
+  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_test_get_property);
+
+  gst_test_signals[TEST_SIGNAL1] =
+      g_signal_new ("test-signal1", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstTestClass, test_signal1), NULL,
+      NULL, gst_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
+  gst_test_signals[TEST_SIGNAL2] =
+      g_signal_new ("test-signal2", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstTestClass, test_signal2), NULL,
+      NULL, gst_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TEST_PROP,
+      g_param_spec_int ("test-prop", "Test Prop", "Test property",
+          0, 1, 0, G_PARAM_READWRITE));
+
+  klass->test_signal2 = signal2_handler;
+}
+
+static void
+gst_test_init (GstTest * test)
+{
+}
+
+static void
+gst_test_dispose (GObject * object)
+{
+  GstTest *test;
+
+  test = GST_TEST (object);
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gst_test_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstTest *test;
+
+  test = GST_TEST (object);
+
+  switch (prop_id) {
+    case ARG_TEST_PROP:
+      g_value_get_int (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_test_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GstTest *test;
+
+  test = GST_TEST (object);
+
+  switch (prop_id) {
+    case ARG_TEST_PROP:
+      g_value_set_int (value, 0);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_test_do_signal1 (GstTest * test)
+{
+  g_signal_emit (G_OBJECT (test), gst_test_signals[TEST_SIGNAL1], 0, 0);
+}
+
+static void
+signal2_handler (GstTest * test, gint anint)
+{
+}
+
+static void
+gst_test_do_signal2 (GstTest * test)
+{
+  g_signal_emit (G_OBJECT (test), gst_test_signals[TEST_SIGNAL2], 0, 0);
+}
+
+static void
+gst_test_do_prop (GstTest * test)
+{
+  g_object_notify (G_OBJECT (test), "test-prop");
+}
+
+static gpointer
+run_thread (GstTest * test)
+{
+  gint i = 0;
+
+  while (TRUE) {
+    if (TESTNUM == 1)
+      gst_test_do_signal1 (test);
+    if (TESTNUM == 2)
+      gst_test_do_signal2 (test);
+    if (TESTNUM == 3)
+      gst_test_do_prop (test);
+    if ((i++ % 10000) == 0)
+      g_print (".");
+  }
+
+  return NULL;
+}
+
+int
+main (int argc, char **argv)
+{
+  gint i;
+  GstTest *test1, *test2;
+
+  gst_init (&argc, &argv);
+
+  test1 = g_object_new (GST_TYPE_TEST, NULL);
+  test2 = g_object_new (GST_TYPE_TEST, NULL);
+
+  for (i = 0; i < 100; i++) {
+    g_thread_create ((GThreadFunc) run_thread, test1, TRUE, NULL);
+    g_thread_create ((GThreadFunc) run_thread, test2, TRUE, NULL);
+  }
+  sleep (5);
+
+  return 0;
+}