(root)/
glib-2.79.0/
gobject/
tests/
signal-handler.c
       1  #include <glib-object.h>
       2  
       3  typedef struct {
       4    GObject instance;
       5  } MyObj;
       6  
       7  typedef struct {
       8    GObjectClass parent_class;
       9  } MyObjClass;
      10  
      11  enum {
      12    SIGNAL1,
      13    SIGNAL2,
      14    LAST_SIGNAL
      15  };
      16  
      17  guint signals[LAST_SIGNAL];
      18  
      19  GType my_obj_get_type (void);
      20  
      21  G_DEFINE_TYPE (MyObj, my_obj, G_TYPE_OBJECT)
      22  
      23  static void
      24  my_obj_init (MyObj *o)
      25  {
      26  }
      27  
      28  static void
      29  my_obj_class_init (MyObjClass *class)
      30  {
      31    signals[SIGNAL1] =
      32      g_signal_new ("signal1",
      33                    G_TYPE_FROM_CLASS (class),
      34                    G_SIGNAL_RUN_LAST,
      35                    0, NULL, NULL, NULL, G_TYPE_NONE, 0);
      36    signals[SIGNAL2] =
      37      g_signal_new ("signal2",
      38                    G_TYPE_FROM_CLASS (class),
      39                    G_SIGNAL_RUN_LAST,
      40                    0, NULL, NULL, NULL, G_TYPE_NONE, 0);
      41  }
      42  
      43  static void
      44  nop (void)
      45  {
      46  }
      47  
      48  static guint n_handlers = 0;
      49  
      50  static void
      51  test_connect_many (void)
      52  {
      53    MyObj *o;
      54    gdouble time_elapsed;
      55    guint i;
      56  
      57    o = g_object_new (my_obj_get_type (), NULL);
      58  
      59    g_test_timer_start ();
      60  
      61    for (i = 0; i < n_handlers; i++)
      62      g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); 
      63  
      64    time_elapsed = g_test_timer_elapsed ();
      65  
      66    g_object_unref (o);
      67  
      68    g_test_minimized_result (time_elapsed, "connected %u handlers in %6.3f seconds", n_handlers, time_elapsed);
      69  }
      70  
      71  static void
      72  test_disconnect_many_ordered (void)
      73  {
      74    MyObj *o;
      75    gulong *handlers;
      76    gdouble time_elapsed;
      77    guint i;
      78  
      79    handlers = g_malloc_n (n_handlers, sizeof (*handlers));
      80    o = g_object_new (my_obj_get_type (), NULL);
      81  
      82    for (i = 0; i < n_handlers; i++)
      83      handlers[i] = g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); 
      84  
      85    g_test_timer_start ();
      86  
      87    for (i = 0; i < n_handlers; i++)
      88      g_signal_handler_disconnect (o, handlers[i]); 
      89  
      90    time_elapsed = g_test_timer_elapsed ();
      91  
      92    g_object_unref (o);
      93    g_free (handlers);
      94  
      95    g_test_minimized_result (time_elapsed, "disconnected %u handlers in %6.3f seconds", n_handlers, time_elapsed);
      96  }
      97  
      98  static void
      99  test_disconnect_many_inverse (void)
     100  {
     101    MyObj *o;
     102    gulong *handlers;
     103    gdouble time_elapsed;
     104    guint i;
     105  
     106    handlers = g_malloc_n (n_handlers, sizeof (*handlers));
     107    o = g_object_new (my_obj_get_type (), NULL);
     108  
     109    for (i = 0; i < n_handlers; i++)
     110      handlers[i] = g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); 
     111  
     112    g_test_timer_start ();
     113  
     114    for (i = n_handlers; i > 0; i--)
     115      g_signal_handler_disconnect (o, handlers[i - 1]);
     116  
     117    time_elapsed = g_test_timer_elapsed ();
     118  
     119    g_object_unref (o);
     120    g_free (handlers);
     121  
     122    g_test_minimized_result (time_elapsed, "disconnected %u handlers in %6.3f seconds", n_handlers, time_elapsed);
     123  }
     124  
     125  static void
     126  test_disconnect_many_random (void)
     127  {
     128    MyObj *o;
     129    gulong *handlers;
     130    gulong id;
     131    gdouble time_elapsed;
     132    guint i, j;
     133  
     134    handlers = g_malloc_n (n_handlers, sizeof (*handlers));
     135    o = g_object_new (my_obj_get_type (), NULL);
     136  
     137    for (i = 0; i < n_handlers; i++)
     138      handlers[i] = g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); 
     139  
     140    for (i = 0; i < n_handlers; i++)
     141      {
     142        j = g_test_rand_int_range (0, n_handlers);
     143        id = handlers[i];
     144        handlers[i] = handlers[j];
     145        handlers[j] = id;
     146      }
     147  
     148    g_test_timer_start ();
     149  
     150    for (i = 0; i < n_handlers; i++)
     151      g_signal_handler_disconnect (o, handlers[i]); 
     152  
     153    time_elapsed = g_test_timer_elapsed ();
     154  
     155    g_object_unref (o);
     156    g_free (handlers);
     157  
     158    g_test_minimized_result (time_elapsed, "disconnected %u handlers in %6.3f seconds", n_handlers, time_elapsed);
     159  }
     160  
     161  static void
     162  test_disconnect_2_signals (void)
     163  {
     164    MyObj *o;
     165    gulong *handlers;
     166    gulong id;
     167    gdouble time_elapsed;
     168    guint i, j;
     169  
     170    handlers = g_malloc_n (n_handlers, sizeof (*handlers));
     171    o = g_object_new (my_obj_get_type (), NULL);
     172  
     173    for (i = 0; i < n_handlers; i++)
     174      {
     175        if (i % 2 == 0)
     176          handlers[i] = g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); 
     177        else
     178          handlers[i] = g_signal_connect (o, "signal2", G_CALLBACK (nop), NULL); 
     179      }
     180  
     181    for (i = 0; i < n_handlers; i++)
     182      {
     183        j = g_test_rand_int_range (0, n_handlers);
     184        id = handlers[i];
     185        handlers[i] = handlers[j];
     186        handlers[j] = id;
     187      }
     188  
     189    g_test_timer_start ();
     190  
     191    for (i = 0; i < n_handlers; i++)
     192      g_signal_handler_disconnect (o, handlers[i]); 
     193  
     194    time_elapsed = g_test_timer_elapsed ();
     195  
     196    g_object_unref (o);
     197    g_free (handlers);
     198  
     199    g_test_minimized_result (time_elapsed, "disconnected %u handlers in %6.3f seconds", n_handlers, time_elapsed);
     200  }
     201  
     202  static void
     203  test_disconnect_2_objects (void)
     204  {
     205    MyObj *o1, *o2, *o;
     206    gulong *handlers;
     207    MyObj **objects;
     208    gulong id;
     209    gdouble time_elapsed;
     210    guint i, j;
     211  
     212    handlers = g_malloc_n (n_handlers, sizeof (*handlers));
     213    objects = g_malloc_n (n_handlers, sizeof (*objects));
     214    o1 = g_object_new (my_obj_get_type (), NULL);
     215    o2 = g_object_new (my_obj_get_type (), NULL);
     216  
     217    for (i = 0; i < n_handlers; i++)
     218      {
     219        if (i % 2 == 0)
     220          {
     221            handlers[i] = g_signal_connect (o1, "signal1", G_CALLBACK (nop), NULL); 
     222            objects[i] = o1;
     223          }
     224        else
     225          {
     226            handlers[i] = g_signal_connect (o2, "signal1", G_CALLBACK (nop), NULL); 
     227            objects[i] = o2;
     228          }
     229      }
     230  
     231    for (i = 0; i < n_handlers; i++)
     232      {
     233        j = g_test_rand_int_range (0, n_handlers);
     234        id = handlers[i];
     235        handlers[i] = handlers[j];
     236        handlers[j] = id;
     237        o = objects[i];
     238        objects[i] = objects[j];
     239        objects[j] = o;
     240      }
     241  
     242    g_test_timer_start ();
     243  
     244    for (i = 0; i < n_handlers; i++)
     245      g_signal_handler_disconnect (objects[i], handlers[i]); 
     246  
     247    time_elapsed = g_test_timer_elapsed ();
     248  
     249    g_object_unref (o1);
     250    g_object_unref (o2);
     251    g_free (objects);
     252    g_free (handlers);
     253  
     254    g_test_minimized_result (time_elapsed, "disconnected %u handlers in %6.3f seconds", n_handlers, time_elapsed);
     255  }
     256  
     257  static void
     258  test_block_many (void)
     259  {
     260    MyObj *o;
     261    gulong *handlers;
     262    gulong id;
     263    gdouble time_elapsed;
     264    guint i, j;
     265  
     266    handlers = g_malloc_n (n_handlers, sizeof (*handlers));
     267    o = g_object_new (my_obj_get_type (), NULL);
     268  
     269    for (i = 0; i < n_handlers; i++)
     270      handlers[i] = g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); 
     271  
     272    for (i = 0; i < n_handlers; i++)
     273      {
     274        j = g_test_rand_int_range (0, n_handlers);
     275        id = handlers[i];
     276        handlers[i] = handlers[j];
     277        handlers[j] = id;
     278      }
     279  
     280    g_test_timer_start ();
     281  
     282    for (i = 0; i < n_handlers; i++)
     283      g_signal_handler_block (o, handlers[i]); 
     284  
     285    for (i = n_handlers; i > 0; i--)
     286      g_signal_handler_unblock (o, handlers[i - 1]);
     287  
     288    time_elapsed = g_test_timer_elapsed ();
     289  
     290    g_object_unref (o);
     291    g_free (handlers);
     292  
     293    g_test_minimized_result (time_elapsed, "blocked and unblocked %u handlers in %6.3f seconds", n_handlers, time_elapsed);
     294  }
     295  
     296  int
     297  main (int argc, char *argv[])
     298  {
     299    g_test_init (&argc, &argv, NULL);
     300  
     301    n_handlers = g_test_perf () ? 500000 : 1;
     302  
     303    g_test_add_func ("/signal/handler/connect-many", test_connect_many);
     304    g_test_add_func ("/signal/handler/disconnect-many-ordered", test_disconnect_many_ordered);
     305    g_test_add_func ("/signal/handler/disconnect-many-inverse", test_disconnect_many_inverse);
     306    g_test_add_func ("/signal/handler/disconnect-many-random", test_disconnect_many_random);
     307    g_test_add_func ("/signal/handler/disconnect-2-signals", test_disconnect_2_signals);
     308    g_test_add_func ("/signal/handler/disconnect-2-objects", test_disconnect_2_objects);
     309    g_test_add_func ("/signal/handler/block-many", test_block_many);
     310  
     311    return g_test_run ();
     312  }