1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 2000 Tor Lillqvist
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 /* A test program for the main loop and IO channel code.
21 * Just run it. Optional parameter is number of sub-processes.
24 #undef G_DISABLE_ASSERT
42 #define pipe(fds) _pipe(fds, 4096, _O_BINARY)
50 static GMainLoop
*main_loop
;
52 #define BUFSIZE 5000 /* Larger than the circular buffer in
53 * giowin32.c on purpose.
72 GIOError error
= G_IO_ERROR_NONE
;
75 /* g_io_channel_read() doesn't necessarily return all the
76 * data we want at once.
81 error
= g_io_channel_read (channel
, bufp
, left
, &nb
);
83 if (error
!= G_IO_ERROR_NONE
)
85 g_print ("gio-test: ...from %d: %d\n", fd
, error
);
86 if (error
== G_IO_ERROR_AGAIN
)
100 shutdown_source (gpointer data
)
102 if (g_source_remove (*(guint
*) data
))
106 g_main_loop_quit (main_loop
);
111 recv_message (GIOChannel
*channel
,
115 gint fd
= g_io_channel_unix_get_fd (channel
);
116 gboolean retval
= TRUE
;
119 g_print ("gio-test: ...from %d:%s%s%s%s\n", fd
,
120 (cond
& G_IO_ERR
) ? " ERR" : "",
121 (cond
& G_IO_HUP
) ? " HUP" : "",
122 (cond
& G_IO_IN
) ? " IN" : "",
123 (cond
& G_IO_PRI
) ? " PRI" : "");
126 if (cond
& (G_IO_ERR
| G_IO_HUP
))
128 shutdown_source (data
);
140 error
= read_all (fd
, channel
, (gchar
*) &seq
, sizeof (seq
), &nb
);
141 if (error
== G_IO_ERROR_NONE
)
146 g_print ("gio-test: ...from %d: EOF\n", fd
);
148 shutdown_source (data
);
152 g_assert (nb
== sizeof (nbytes
));
154 for (i
= 0; i
< nkiddies
; i
++)
155 if (seqtab
[i
].fd
== fd
)
157 g_assert_cmpint (seq
, ==, seqtab
[i
].seq
);
162 error
= read_all (fd
, channel
, (gchar
*) &nbytes
, sizeof (nbytes
), &nb
);
165 if (error
!= G_IO_ERROR_NONE
)
171 g_print ("gio-test: ...from %d: EOF\n", fd
);
173 shutdown_source (data
);
177 g_assert (nb
== sizeof (nbytes
));
179 g_assert_cmpint (nbytes
, <, BUFSIZE
);
180 g_assert (nbytes
>= 0 && nbytes
< BUFSIZE
);
182 g_print ("gio-test: ...from %d: %d bytes\n", fd
, nbytes
);
186 error
= read_all (fd
, channel
, buf
, nbytes
, &nb
);
188 if (error
!= G_IO_ERROR_NONE
)
194 g_print ("gio-test: ...from %d: EOF\n", fd
);
196 shutdown_source (data
);
200 for (j
= 0; j
< nbytes
; j
++)
201 g_assert (buf
[j
] == ' ' + ((nbytes
+ j
) % 95));
203 g_print ("gio-test: ...from %d: OK\n", fd
);
213 recv_windows_message (GIOChannel
*channel
,
223 error
= g_io_channel_read (channel
, &msg
, sizeof (MSG
), &nb
);
225 if (error
!= G_IO_ERROR_NONE
)
227 g_print ("gio-test: ...reading Windows message: G_IO_ERROR_%s\n",
228 (error
== G_IO_ERROR_AGAIN
? "AGAIN" :
229 (error
== G_IO_ERROR_INVAL
? "INVAL" :
230 (error
== G_IO_ERROR_UNKNOWN
? "UNKNOWN" : "???"))));
231 if (error
== G_IO_ERROR_AGAIN
)
237 g_print ("gio-test: ...Windows message for %#x: %d,%d,%d\n",
238 msg
.hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
);
244 window_procedure (HWND hwnd
,
249 g_print ("gio-test: window_procedure for %#x: %d,%d,%d\n",
250 hwnd
, message
, wparam
, lparam
);
251 return DefWindowProc (hwnd
, message
, wparam
, lparam
);
264 GIOChannel
*my_read_channel
;
275 GIOChannel
*windows_messages_channel
;
278 nkiddies
= (argc
== 1 ? 1 : atoi(argv
[1]));
279 seqtab
= g_malloc (nkiddies
* 2 * sizeof (int));
283 wcl
.lpfnWndProc
= window_procedure
;
286 wcl
.hInstance
= GetModuleHandle (NULL
);
289 wcl
.hbrBackground
= NULL
;
290 wcl
.lpszMenuName
= NULL
;
291 wcl
.lpszClassName
= "gio-test";
293 klass
= RegisterClass (&wcl
);
297 g_print ("gio-test: RegisterClass failed\n");
301 hwnd
= CreateWindow (MAKEINTATOM(klass
), "gio-test", 0, 0, 0, 10, 10,
302 NULL
, NULL
, wcl
.hInstance
, NULL
);
305 g_print ("gio-test: CreateWindow failed\n");
309 windows_messages_channel
= g_io_channel_win32_new_messages ((guint
)hwnd
);
310 g_io_add_watch (windows_messages_channel
, G_IO_IN
, recv_windows_message
, 0);
313 for (i
= 0; i
< nkiddies
; i
++)
315 int pipe_to_sub
[2], pipe_from_sub
[2];
317 if (pipe (pipe_to_sub
) == -1 ||
318 pipe (pipe_from_sub
) == -1)
319 perror ("pipe"), exit (1);
321 seqtab
[i
].fd
= pipe_from_sub
[0];
324 my_read_channel
= g_io_channel_unix_new (pipe_from_sub
[0]);
326 id
= g_new (guint
, 1);
328 g_io_add_watch (my_read_channel
,
329 G_IO_IN
| G_IO_PRI
| G_IO_ERR
| G_IO_HUP
,
336 cmdline
= g_strdup_printf ("%d:%d:%d",
340 _spawnl (_P_NOWAIT
, argv
[0], argv
[0], "--child", cmdline
, NULL
);
342 cmdline
= g_strdup_printf ("%s --child %d:%d &", argv
[0],
343 pipe_to_sub
[0], pipe_from_sub
[1]);
347 close (pipe_to_sub
[0]);
348 close (pipe_from_sub
[1]);
351 g_get_current_time (&start
);
352 g_io_channel_win32_make_pollfd (my_read_channel
, G_IO_IN
, &pollfd
);
353 pollresult
= g_io_channel_win32_poll (&pollfd
, 1, 100);
354 g_get_current_time (&end
);
355 if (end
.tv_usec
< start
.tv_usec
)
356 end
.tv_sec
--, end
.tv_usec
+= 1000000;
357 g_print ("gio-test: had to wait %ld.%03ld s, result:%d\n",
358 end
.tv_sec
- start
.tv_sec
,
359 (end
.tv_usec
- start
.tv_usec
) / 1000,
364 main_loop
= g_main_loop_new (NULL
, FALSE
);
366 g_main_loop_run (main_loop
);
382 g_get_current_time (&tv
);
384 sscanf (argv
[2], "%d:%d%n", &readfd
, &writefd
, &n
);
387 sscanf (argv
[2] + n
, ":%d", &hwnd
);
390 srand (tv
.tv_sec
^ (tv
.tv_usec
/ 1000) ^ readfd
^ (writefd
<< 4));
392 for (i
= 0; i
< 20 + rand() % 20; i
++)
394 g_usleep (100 + (rand() % 10) * 5000);
395 buflen
= rand() % BUFSIZE
;
396 for (j
= 0; j
< buflen
; j
++)
397 buf
[j
] = ' ' + ((buflen
+ j
) % 95);
399 g_print ("gio-test: child writing %d+%d bytes to %d\n",
400 (int)(sizeof(i
) + sizeof(buflen
)), buflen
, writefd
);
402 write (writefd
, &i
, sizeof (i
));
403 write (writefd
, &buflen
, sizeof (buflen
));
404 write (writefd
, buf
, buflen
);
407 if (rand() % 100 < 5)
409 int msg
= WM_USER
+ (rand() % 100);
410 WPARAM wparam
= rand ();
411 LPARAM lparam
= rand ();
412 g_print ("gio-test: child posting message %d,%d,%d to %#x\n",
413 msg
, wparam
, lparam
, hwnd
);
414 PostMessage (hwnd
, msg
, wparam
, lparam
);
419 g_print ("gio-test: child exiting, closing %d\n", writefd
);