(root)/
glib-2.79.0/
gobject/
tests/
closure.c
       1  #include <glib-object.h>
       2  
       3  #ifdef G_OS_UNIX
       4  #include <glib-unix.h>
       5  
       6  #include <fcntl.h>
       7  #include <signal.h>
       8  #include <unistd.h>
       9  #endif
      10  
      11  static void
      12  test_source (GSource *one, GCallback quit_callback)
      13  {
      14    GClosure *closure;
      15    GMainLoop *loop;
      16  
      17    /* Callback with GMainLoop user_data */
      18    loop = g_main_loop_new (NULL, FALSE);
      19  
      20    closure = g_cclosure_new (quit_callback, loop, NULL);
      21    g_source_set_closure (one, closure);
      22  
      23    g_source_attach (one, NULL);
      24    g_main_loop_run (loop);
      25  
      26    g_source_destroy (one);
      27    g_main_loop_unref (loop);
      28  }
      29  
      30  static gboolean
      31  simple_quit_callback (gpointer user_data)
      32  {
      33    GMainLoop *loop = user_data;
      34  
      35    g_main_loop_quit (loop);
      36  
      37    return TRUE;
      38  }
      39  
      40  static void
      41  test_closure_idle (void)
      42  {
      43    GSource *source;
      44  
      45    source = g_idle_source_new ();
      46    test_source (source, G_CALLBACK (simple_quit_callback));
      47    g_source_unref (source);
      48  }
      49  
      50  static void
      51  test_closure_timeout (void)
      52  {
      53    GSource *source;
      54  
      55    source = g_timeout_source_new (10);
      56    test_source (source, G_CALLBACK (simple_quit_callback));
      57    g_source_unref (source);
      58  }
      59  
      60  static gboolean
      61  iochannel_quit_callback (GIOChannel   *channel,
      62                           GIOCondition  cond,
      63                           gpointer      user_data)
      64  {
      65    GMainLoop *loop = user_data;
      66  
      67    g_main_loop_quit (loop);
      68  
      69    return TRUE;
      70  }
      71  
      72  static void
      73  test_closure_iochannel (void)
      74  {
      75    GIOChannel *chan;
      76    GSource *source;
      77    char *path;
      78    GError *error = NULL;
      79  
      80    if (g_path_is_absolute (g_get_prgname ()))
      81      path = g_strdup (g_get_prgname ());
      82    else
      83      {
      84        path = g_test_build_filename (G_TEST_BUILT,
      85                                      g_get_prgname (),
      86                                      NULL);
      87      }
      88    chan = g_io_channel_new_file (path, "r", &error);
      89    g_assert_no_error (error);
      90    g_free (path);
      91  
      92    source = g_io_create_watch (chan, G_IO_IN);
      93    test_source (source, G_CALLBACK (iochannel_quit_callback));
      94    g_source_unref (source);
      95  
      96    g_io_channel_unref (chan);
      97  }
      98  
      99  static void
     100  test_closure_child (void)
     101  {
     102    GSource *source;
     103    GPid pid;
     104    GError *error = NULL;
     105    gchar *argv[3];
     106  
     107    g_assert (g_getenv ("DO_NOT_ACCIDENTALLY_RECURSE") == NULL);
     108    g_setenv ("DO_NOT_ACCIDENTALLY_RECURSE", "1", TRUE);
     109  
     110    if (g_path_is_absolute (g_get_prgname ()))
     111      argv[0] = g_strdup (g_get_prgname ());
     112    else
     113      {
     114        argv[0] = g_test_build_filename (G_TEST_BUILT,
     115                                         g_get_prgname (),
     116                                         NULL);
     117      }
     118    argv[1] = "-l";
     119    argv[2] = NULL;
     120  
     121    g_spawn_async (NULL, argv, NULL,
     122                   G_SPAWN_STDOUT_TO_DEV_NULL |
     123                   G_SPAWN_STDERR_TO_DEV_NULL |
     124                   G_SPAWN_DO_NOT_REAP_CHILD,
     125                   NULL, NULL,
     126                   &pid, &error);
     127    g_assert_no_error (error);
     128  
     129    g_free (argv[0]);
     130  
     131    source = g_child_watch_source_new (pid);
     132    test_source (source, G_CALLBACK (iochannel_quit_callback));
     133    g_source_unref (source);
     134  }
     135  
     136  #ifdef G_OS_UNIX
     137  static gboolean
     138  fd_quit_callback (gint         fd,
     139                    GIOCondition condition,
     140                    gpointer     user_data)
     141  {
     142    GMainLoop *loop = user_data;
     143  
     144    g_main_loop_quit (loop);
     145  
     146    return TRUE;
     147  }
     148  
     149  static void
     150  test_closure_fd (void)
     151  {
     152    gint fd;
     153    GSource *source;
     154  
     155    fd = open ("/dev/null", O_RDONLY);
     156    g_assert (fd != -1);
     157  
     158    source = g_unix_fd_source_new (fd, G_IO_IN);
     159    test_source (source, G_CALLBACK (fd_quit_callback));
     160    g_source_unref (source);
     161  
     162    close (fd);
     163  }
     164  
     165  static gboolean
     166  send_usr1 (gpointer user_data)
     167  {
     168    kill (getpid (), SIGUSR1);
     169    return FALSE;
     170  }
     171  
     172  static gboolean
     173  closure_quit_callback (gpointer     user_data)
     174  {
     175    GMainLoop *loop = user_data;
     176  
     177    g_main_loop_quit (loop);
     178  
     179    return TRUE;
     180  }
     181  
     182  static void
     183  test_closure_signal (void)
     184  {
     185    GSource *source;
     186  
     187    g_idle_add_full (G_PRIORITY_LOW, send_usr1, NULL, NULL);
     188  
     189    source = g_unix_signal_source_new (SIGUSR1);
     190    test_source (source, G_CALLBACK (closure_quit_callback));
     191    g_source_unref (source);
     192  }
     193  #endif
     194  
     195  int
     196  main (int argc,
     197        char *argv[])
     198  {
     199  #ifndef G_OS_WIN32
     200    sigset_t sig_mask, old_mask;
     201  
     202    sigemptyset (&sig_mask);
     203    sigaddset (&sig_mask, SIGUSR1);
     204    if (sigprocmask (SIG_UNBLOCK, &sig_mask, &old_mask) == 0)
     205      {
     206        if (sigismember (&old_mask, SIGUSR1))
     207          g_message ("SIGUSR1 was blocked, unblocking it");
     208      }
     209  #endif
     210  
     211    g_test_init (&argc, &argv, NULL);
     212  
     213    g_test_add_func ("/closure/idle", test_closure_idle);
     214    g_test_add_func ("/closure/timeout", test_closure_timeout);
     215    g_test_add_func ("/closure/iochannel", test_closure_iochannel);
     216    g_test_add_func ("/closure/child", test_closure_child);
     217  #ifdef G_OS_UNIX
     218    g_test_add_func ("/closure/fd", test_closure_fd);
     219    g_test_add_func ("/closure/signal", test_closure_signal);
     220  #endif
     221  
     222    return g_test_run ();
     223  }