glib/tests/timeloop-closure.c
changeset 18 47c74d1534e1
child 34 5fae379060a7
equal deleted inserted replaced
0:e4d67989cc36 18:47c74d1534e1
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 #undef G_DISABLE_ASSERT
       
    19 #undef G_LOG_DOMAIN
       
    20 
       
    21 #include <errno.h>
       
    22 #include <stdlib.h>
       
    23 #include <unistd.h>
       
    24 #include <stdio.h>
       
    25 #include <sys/time.h>
       
    26 #include <sys/resource.h>
       
    27 
       
    28 #include <glib.h>
       
    29 #include <glib-object.h>
       
    30 
       
    31 #ifdef __SYMBIAN32__
       
    32 #include "mrt2_glib2_test.h"
       
    33 #endif /*__SYMBIAN32__*/
       
    34 
       
    35 
       
    36 static int n_children = 3;
       
    37 static int n_active_children;
       
    38 static int n_iters = 10000;
       
    39 static GMainLoop *loop;
       
    40 
       
    41 static void
       
    42 io_pipe (GIOChannel **channels)
       
    43 {
       
    44   int fds[2];
       
    45 
       
    46   if (pipe(fds) < 0)
       
    47     {
       
    48       fprintf (stderr, "Cannot create pipe %s\n", g_strerror (errno));
       
    49       exit (1);
       
    50     }
       
    51 
       
    52   channels[0] = g_io_channel_unix_new (fds[0]);
       
    53   channels[1] = g_io_channel_unix_new (fds[1]);
       
    54 }
       
    55 
       
    56 static gboolean
       
    57 read_all (GIOChannel *channel, char *buf, int len)
       
    58 {
       
    59   gsize bytes_read = 0;
       
    60   gsize count;
       
    61   GIOError err;
       
    62 
       
    63   while (bytes_read < len)
       
    64     {
       
    65       err = g_io_channel_read (channel, buf + bytes_read, len - bytes_read, &count);
       
    66       if (err)
       
    67 	{
       
    68 	  if (err != G_IO_ERROR_AGAIN)
       
    69 	    return FALSE;
       
    70 	}
       
    71       else if (count == 0)
       
    72 	return FALSE;
       
    73 
       
    74       bytes_read += count;
       
    75     }
       
    76 
       
    77   return TRUE;
       
    78 }
       
    79 
       
    80 static gboolean
       
    81 write_all (GIOChannel *channel, char *buf, int len)
       
    82 {
       
    83   gsize bytes_written = 0;
       
    84   gsize count;
       
    85   GIOError err;
       
    86 
       
    87   while (bytes_written < len)
       
    88     {
       
    89       err = g_io_channel_write (channel, buf + bytes_written, len - bytes_written, &count);
       
    90       if (err && err != G_IO_ERROR_AGAIN)
       
    91 	return FALSE;
       
    92 
       
    93       bytes_written += count;
       
    94     }
       
    95 
       
    96   return TRUE;
       
    97 }
       
    98 
       
    99 #ifndef __SYMBIAN32__
       
   100 static void
       
   101 run_child (GIOChannel *in_channel, GIOChannel *out_channel)
       
   102 #else
       
   103 gpointer
       
   104 run_child (gpointer data)
       
   105 #endif//__SYMBIAN32__
       
   106 {
       
   107   int i;
       
   108   int val = 1;
       
   109 #ifdef  __SYMBIAN32__ 
       
   110   GIOChannel *in_channel,*out_channel;
       
   111 #endif//__SYMBIAN32__  
       
   112   GTimer *timer = g_timer_new();
       
   113 #ifdef __SYMBIAN32__  
       
   114   GIOChannel **channels = data;
       
   115   
       
   116   in_channel = channels[0];
       
   117   out_channel = channels[1];
       
   118 #endif//__SYMBIAN32__
       
   119   for (i = 0; i < n_iters; i++)
       
   120     {
       
   121       write_all (out_channel, (char *)&val, sizeof (val));
       
   122       read_all (in_channel, (char *)&val, sizeof (val));
       
   123     }
       
   124 
       
   125   val = 0;
       
   126   write_all (out_channel, (char *)&val, sizeof (val));
       
   127 
       
   128   val = g_timer_elapsed (timer, NULL) * 1000;
       
   129   
       
   130   write_all (out_channel, (char *)&val, sizeof (val));
       
   131   g_timer_destroy (timer);
       
   132 #ifndef  __SYMBIAN32__
       
   133   exit (0);
       
   134 #else
       
   135   return NULL;
       
   136 #endif//__SYMBIAN32__    
       
   137 }
       
   138 
       
   139 static gboolean
       
   140 input_callback (GIOChannel   *source,
       
   141 		GIOCondition  condition,
       
   142 		gpointer      data)
       
   143 {
       
   144   int val;
       
   145   GIOChannel *dest = (GIOChannel *)data;
       
   146   
       
   147   if (!read_all (source, (char *)&val, sizeof(val)))
       
   148     {
       
   149       fprintf (stderr, "Unexpected EOF\n");
       
   150       exit (1);
       
   151     }
       
   152 
       
   153   if (val)
       
   154     {
       
   155       write_all (dest, (char *)&val, sizeof(val));
       
   156       
       
   157       return TRUE;
       
   158     }
       
   159   else
       
   160     {
       
   161       g_io_channel_close (source);
       
   162       g_io_channel_close (dest);
       
   163       
       
   164       g_io_channel_unref (source);
       
   165       g_io_channel_unref (dest);
       
   166 
       
   167       n_active_children--;
       
   168       if (n_active_children == 0)
       
   169 	g_main_loop_quit (loop);
       
   170       
       
   171       return FALSE;
       
   172     }
       
   173 }
       
   174 
       
   175 static void
       
   176 create_child (void)
       
   177 {
       
   178   GError *err;
       
   179   GIOChannel *in_channels[2];
       
   180   GIOChannel *out_channels[2];
       
   181   GIOChannel **sub_channels;
       
   182   GSource *source;
       
   183   
       
   184   sub_channels = g_new (GIOChannel *, 2);
       
   185   
       
   186   io_pipe (in_channels);
       
   187   io_pipe (out_channels);
       
   188   
       
   189   sub_channels[0] = in_channels[0];
       
   190   sub_channels[1] = out_channels[1];
       
   191 
       
   192   source = g_io_create_watch (out_channels[0], G_IO_IN | G_IO_HUP);
       
   193   g_assert(source != NULL);
       
   194   g_source_set_closure (source,
       
   195   g_cclosure_new (G_CALLBACK (input_callback), in_channels[1], NULL));
       
   196   g_source_attach (source, NULL);
       
   197 
       
   198   g_thread_create(run_child,sub_channels,FALSE,&err);
       
   199 
       
   200 }
       
   201 
       
   202 static double 
       
   203 difftimeval (struct timeval *old, struct timeval *new)
       
   204 {
       
   205   return
       
   206     (new->tv_sec - old->tv_sec) * 1000. + (new->tv_usec - old->tv_usec) / 1000;
       
   207 }
       
   208 
       
   209 int 
       
   210 main (int argc, char **argv)
       
   211 {
       
   212   int i;
       
   213 
       
   214   #ifdef __SYMBIAN32__
       
   215   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);
       
   216   g_set_print_handler(mrtPrintHandler);
       
   217   #endif /*__SYMBIAN32__*/
       
   218    
       
   219   g_thread_init(NULL);
       
   220 	  
       
   221   g_type_init ();
       
   222   
       
   223   if (argc > 1)
       
   224     n_children = atoi(argv[1]);
       
   225 
       
   226   if (argc > 2)
       
   227     n_iters = atoi(argv[2]);
       
   228 
       
   229   printf ("Children: %d     Iters: %d\n", n_children, n_iters);
       
   230 
       
   231   n_active_children = n_children;
       
   232   for (i = 0; i < n_children; i++)
       
   233     create_child ();
       
   234 
       
   235   loop = g_main_loop_new (NULL, FALSE);
       
   236   
       
   237   g_assert(loop != NULL);
       
   238   
       
   239   g_main_loop_run (loop);
       
   240   
       
   241   g_assert(n_active_children == 0);
       
   242   
       
   243   
       
   244 #ifdef __SYMBIAN32__
       
   245   testResultXml("timeloop-closure");
       
   246 #endif /* EMULATOR */
       
   247   return 0;
       
   248 }