os/ossrv/glib/tsrc/BC/tests/timeloop-closure.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 }