glib/tsrc/BC/tests/timeloop-closure.c
changeset 31 ce057bb09d0b
parent 0 e4d67989cc36
equal deleted inserted replaced
30:e20de85af2ee 31:ce057bb09d0b
       
     1 /* Portion Copyright © 2008-09 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.*/
       
     2 #undef G_DISABLE_ASSERT
       
     3 #undef G_LOG_DOMAIN
       
     4 
       
     5 #include <errno.h>
       
     6 #include <stdlib.h>
       
     7 #include <unistd.h>
       
     8 #include <stdio.h>
       
     9 #include <sys/time.h>
       
    10 #include <sys/resource.h>
       
    11 
       
    12 #include <glib.h>
       
    13 #include <glib-object.h>
       
    14 
       
    15 #ifdef SYMBIAN
       
    16 #include "mrt2_glib2_test.h"
       
    17 #endif /*SYMBIAN*/
       
    18 
       
    19 
       
    20 static int n_children = 4;
       
    21 static int n_active_children;
       
    22 static int n_iters = 5;
       
    23 static GMainLoop *loop;
       
    24 
       
    25 static void
       
    26 io_pipe (GIOChannel **channels)
       
    27 {
       
    28   int fds[2];
       
    29 
       
    30   if (pipe(fds) < 0)
       
    31     {
       
    32       g_print("Cannot create pipe %s\n", g_strerror (errno));
       
    33       exit (1);
       
    34     }
       
    35 
       
    36   channels[0] = g_io_channel_unix_new (fds[0]);
       
    37   channels[1] = g_io_channel_unix_new (fds[1]);
       
    38 }
       
    39 
       
    40 static gboolean
       
    41 read_all (GIOChannel *channel, char *buf, int len)
       
    42 {
       
    43   gsize bytes_read = 0;
       
    44   gsize count;
       
    45   GIOError err;
       
    46 
       
    47   while (bytes_read < len)
       
    48     {
       
    49       err = g_io_channel_read (channel, buf + bytes_read, len - bytes_read, &count);
       
    50       if (err)
       
    51 	{
       
    52 	  if (err != G_IO_ERROR_AGAIN)
       
    53 	    return FALSE;
       
    54 	}
       
    55       else if (count == 0)
       
    56 	return FALSE;
       
    57 
       
    58       bytes_read += count;
       
    59     }
       
    60 
       
    61   return TRUE;
       
    62 }
       
    63 
       
    64 static gboolean
       
    65 write_all (GIOChannel *channel, char *buf, int len)
       
    66 {
       
    67   gsize bytes_written = 0;
       
    68   gsize count;
       
    69   GIOError err;
       
    70 
       
    71   while (bytes_written < len)
       
    72     {
       
    73       err = g_io_channel_write (channel, buf + bytes_written, len - bytes_written, &count);
       
    74       if (err && err != G_IO_ERROR_AGAIN)
       
    75 	return FALSE;
       
    76 
       
    77       bytes_written += count;
       
    78     }
       
    79 
       
    80   return TRUE;
       
    81 }
       
    82 
       
    83 gpointer
       
    84 run_child (gpointer data)
       
    85 {
       
    86   int i;
       
    87   int val = 1;
       
    88   GIOChannel *in_channel,*out_channel;
       
    89   GTimer *timer = g_timer_new();
       
    90   
       
    91   GIOChannel **channels = data;
       
    92   
       
    93   in_channel = channels[0];
       
    94   out_channel = channels[1];
       
    95 
       
    96   for (i = 0; i < n_iters; i++)
       
    97     {
       
    98       write_all (out_channel, (char *)&val, sizeof (val));
       
    99       read_all (in_channel, (char *)&val, sizeof (val));
       
   100     }
       
   101 
       
   102   val = 0;
       
   103   write_all (out_channel, (char *)&val, sizeof (val));
       
   104 
       
   105   val = g_timer_elapsed (timer, NULL) * 1000;
       
   106   
       
   107   write_all (out_channel, (char *)&val, sizeof (val));
       
   108   g_timer_destroy (timer);
       
   109 
       
   110   return NULL;
       
   111 }
       
   112 
       
   113 static gboolean
       
   114 input_callback (GIOChannel   *source,
       
   115 		GIOCondition  condition,
       
   116 		gpointer      data)
       
   117 {
       
   118   int val;
       
   119   GIOChannel *dest = (GIOChannel *)data;
       
   120   
       
   121   if (!read_all (source, (char *)&val, sizeof(val)))
       
   122     {
       
   123       g_print("Unexpected EOF\n");
       
   124       exit (1);
       
   125     }
       
   126 
       
   127   if (val)
       
   128     {
       
   129       write_all (dest, (char *)&val, sizeof(val));
       
   130       
       
   131       return TRUE;
       
   132     }
       
   133   else
       
   134     {
       
   135       g_io_channel_close (source);
       
   136       g_io_channel_close (dest);
       
   137       
       
   138       g_io_channel_unref (source);
       
   139       g_io_channel_unref (dest);
       
   140 
       
   141       n_active_children--;
       
   142       if (n_active_children == 0)
       
   143 	g_main_loop_quit (loop);
       
   144       
       
   145       return FALSE;
       
   146     }
       
   147 }
       
   148 
       
   149 static void
       
   150 create_child (void)
       
   151 {
       
   152   GError *err;
       
   153   GIOChannel *in_channels[2];
       
   154   GIOChannel *out_channels[2];
       
   155   GIOChannel **sub_channels;
       
   156   GSource *source;
       
   157   
       
   158   sub_channels = g_new (GIOChannel *, 2);
       
   159   
       
   160   io_pipe (in_channels);
       
   161   io_pipe (out_channels);
       
   162   
       
   163   sub_channels[0] = in_channels[0];
       
   164   sub_channels[1] = out_channels[1];
       
   165 
       
   166   source = g_io_create_watch (out_channels[0], G_IO_IN | G_IO_HUP);
       
   167   g_assert(source != NULL);
       
   168   g_source_set_closure (source,
       
   169   g_cclosure_new (G_CALLBACK (input_callback), in_channels[1], NULL));
       
   170   g_source_attach (source, NULL);
       
   171 
       
   172   g_thread_create(run_child,sub_channels,FALSE,&err);
       
   173 
       
   174 }
       
   175 
       
   176 
       
   177 int 
       
   178 main (int argc, char **argv)
       
   179 {
       
   180   int i;
       
   181   
       
   182   #ifdef SYMBIAN
       
   183   g_log_set_handler (NULL,  G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, &mrtLogHandler, NULL);
       
   184   #endif /*SYMBIAN*/
       
   185    
       
   186   g_thread_init(NULL);
       
   187 	  
       
   188   g_type_init ();
       
   189   
       
   190   if (argc > 1)
       
   191     n_children = atoi(argv[1]);
       
   192 
       
   193   if (argc > 2)
       
   194     n_iters = atoi(argv[2]);
       
   195 
       
   196   n_active_children = n_children;
       
   197   for (i = 0; i < n_children; i++)
       
   198     create_child ();
       
   199 
       
   200   loop = g_main_loop_new (NULL, FALSE);
       
   201   
       
   202   g_assert(loop != NULL);
       
   203   
       
   204   g_main_loop_run (loop);
       
   205   
       
   206   g_assert(n_active_children == 0);
       
   207   
       
   208   
       
   209 #ifdef SYMBIAN
       
   210   testResultXml("timeloop-closure");
       
   211 #endif /* EMULATOR */
       
   212   return 0;
       
   213 }