X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=tests%2Fgio-test.c;h=f0f70cd78eecd738359149f93646330fa8ca4ff0;hb=6f7dc3a44f966e69a7495cd5af5017ec02b3938c;hp=cbdbe60ada7cfd229b54e1a78a012141749eab62;hpb=b965bb5db1732cee8e0ed92d6484921a1431d6a9;p=platform%2Fupstream%2Fglib.git diff --git a/tests/gio-test.c b/tests/gio-test.c index cbdbe60..f0f70cd 100644 --- a/tests/gio-test.c +++ b/tests/gio-test.c @@ -12,15 +12,16 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library; if not, see . */ /* A test program for the main loop and IO channel code. - * Just run it. + * Just run it. Optional parameter is number of sub-processes. */ +#undef G_DISABLE_ASSERT +#undef G_LOG_DOMAIN + #include "config.h" #include @@ -34,10 +35,13 @@ #include #include #include -#else - #ifdef HAVE_UNISTD_H - #include - #endif + #define STRICT + #include + #define pipe(fds) _pipe(fds, 4096, _O_BINARY) +#endif + +#ifdef G_OS_UNIX + #include #endif static int nrunning; @@ -54,25 +58,73 @@ static struct { int seq; } *seqtab; +static GIOError +read_all (int fd, + GIOChannel *channel, + char *buffer, + guint nbytes, + guint *bytes_read) +{ + guint left = nbytes; + gsize nb; + GIOError error = G_IO_ERROR_NONE; + char *bufp = buffer; + + /* g_io_channel_read() doesn't necessarily return all the + * data we want at once. + */ + *bytes_read = 0; + while (left) + { + error = g_io_channel_read (channel, bufp, left, &nb); + + if (error != G_IO_ERROR_NONE) + { + g_print ("gio-test: ...from %d: %d\n", fd, error); + if (error == G_IO_ERROR_AGAIN) + continue; + break; + } + if (nb == 0) + return error; + left -= nb; + bufp += nb; + *bytes_read += nb; + } + return error; +} + +static void +shutdown_source (gpointer data) +{ + if (g_source_remove (*(guint *) data)) + { + nrunning--; + if (nrunning == 0) + g_main_loop_quit (main_loop); + } +} + static gboolean recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { gint fd = g_io_channel_unix_get_fd (channel); + gboolean retval = TRUE; - g_print ("testgio: ...from %d:%s%s%s%s\n", fd, +#ifdef VERBOSE + g_print ("gio-test: ...from %d:%s%s%s%s\n", fd, (cond & G_IO_ERR) ? " ERR" : "", (cond & G_IO_HUP) ? " HUP" : "", (cond & G_IO_IN) ? " IN" : "", (cond & G_IO_PRI) ? " PRI" : ""); +#endif if (cond & (G_IO_ERR | G_IO_HUP)) { - g_source_remove (*(guint *) data); - nrunning--; - if (nrunning == 0) - g_main_quit (main_loop); + shutdown_source (data); + retval = FALSE; } if (cond & G_IO_IN) @@ -83,12 +135,15 @@ recv_message (GIOChannel *channel, int i, j, seq; GIOError error; - error = g_io_channel_read (channel, (gchar *) &seq, sizeof (seq), &nb); + error = read_all (fd, channel, (gchar *) &seq, sizeof (seq), &nb); if (error == G_IO_ERROR_NONE) { if (nb == 0) { - g_print ("testgio: ...from %d: EOF\n", fd); +#ifdef VERBOSE + g_print ("gio-test: ...from %d: EOF\n", fd); +#endif + shutdown_source (data); return FALSE; } @@ -97,80 +152,105 @@ recv_message (GIOChannel *channel, for (i = 0; i < nkiddies; i++) if (seqtab[i].fd == fd) { - if (seq != seqtab[i].seq) - { - g_print ("testgio: ...from &d: invalid sequence number %d, expected %d\n", - seq, seqtab[i].seq); - g_assert_not_reached (); - } + g_assert_cmpint (seq, ==, seqtab[i].seq); seqtab[i].seq++; break; } - error = g_io_channel_read (channel, (gchar *) &nbytes, sizeof (nbytes), &nb); + error = read_all (fd, channel, (gchar *) &nbytes, sizeof (nbytes), &nb); } if (error != G_IO_ERROR_NONE) - { - g_print ("testgio: ...from %d: G_IO_ERROR_%s\n", fd, - (error == G_IO_ERROR_AGAIN ? "AGAIN" : - (error == G_IO_ERROR_INVAL ? "INVAL" : - (error == G_IO_ERROR_UNKNOWN ? "UNKNOWN" : "???")))); - - return FALSE; - } + return FALSE; if (nb == 0) { - g_print ("testgio: ...from %d: EOF\n", fd); +#ifdef VERBOSE + g_print ("gio-test: ...from %d: EOF\n", fd); +#endif + shutdown_source (data); return FALSE; } g_assert (nb == sizeof (nbytes)); - if (nbytes >= BUFSIZE) - { - g_print ("testgio: ...from %d: nbytes = %d (%#x)!\n", fd, nbytes, nbytes); - g_assert_not_reached (); - } + g_assert_cmpint (nbytes, <, BUFSIZE); g_assert (nbytes >= 0 && nbytes < BUFSIZE); - - g_print ("testgio: ...from %d: %d bytes\n", fd, nbytes); - +#ifdef VERBOSE + g_print ("gio-test: ...from %d: %d bytes\n", fd, nbytes); +#endif if (nbytes > 0) { - error = g_io_channel_read (channel, buf, nbytes, &nb); - + error = read_all (fd, channel, buf, nbytes, &nb); + if (error != G_IO_ERROR_NONE) - { - g_print ("testgio: ...from %d: G_IO_ERROR_%s\n", fd, - (error == G_IO_ERROR_AGAIN ? "AGAIN" : - (error == G_IO_ERROR_INVAL ? "INVAL" : - (error == G_IO_ERROR_UNKNOWN ? "UNKNOWN" : "???")))); - - return FALSE; - } + return FALSE; - if (nb != nbytes) + if (nb == 0) { - g_print ("testgio: ...from %d: nb=%d != nbytes=%d\n", - fd, nb, nbytes); - g_assert_not_reached (); +#ifdef VERBOSE + g_print ("gio-test: ...from %d: EOF\n", fd); +#endif + shutdown_source (data); + return FALSE; } - + for (j = 0; j < nbytes; j++) - if (buf[j] != ' ' + ((nbytes + j) % 95)) - { - g_print ("testgio: ...from %d: buf[%d] == '%c', should be '%c'\n", - fd, j, buf[j], 'a' + ((nbytes + j) % 32)); - g_assert_not_reached (); - } - g_print ("testgio: ...from %d: OK\n", fd); + g_assert (buf[j] == ' ' + ((nbytes + j) % 95)); +#ifdef VERBOSE + g_print ("gio-test: ...from %d: OK\n", fd); +#endif } } + return retval; +} + +#ifdef G_OS_WIN32 + +static gboolean +recv_windows_message (GIOChannel *channel, + GIOCondition cond, + gpointer data) +{ + GIOError error; + MSG msg; + guint nb; + + while (1) + { + error = g_io_channel_read (channel, &msg, sizeof (MSG), &nb); + + if (error != G_IO_ERROR_NONE) + { + g_print ("gio-test: ...reading Windows message: G_IO_ERROR_%s\n", + (error == G_IO_ERROR_AGAIN ? "AGAIN" : + (error == G_IO_ERROR_INVAL ? "INVAL" : + (error == G_IO_ERROR_UNKNOWN ? "UNKNOWN" : "???")))); + if (error == G_IO_ERROR_AGAIN) + continue; + } + break; + } + + g_print ("gio-test: ...Windows message for %#x: %d,%d,%d\n", + msg.hwnd, msg.message, msg.wParam, msg.lParam); + return TRUE; } +LRESULT CALLBACK +window_procedure (HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam) +{ + g_print ("gio-test: window_procedure for %#x: %d,%d,%d\n", + hwnd, message, wparam, lparam); + return DefWindowProc (hwnd, message, wparam, lparam); +} + +#endif + int main (int argc, char **argv) @@ -185,12 +265,49 @@ main (int argc, int i; #ifdef G_OS_WIN32 GTimeVal start, end; + GPollFD pollfd; int pollresult; + ATOM klass; + static WNDCLASS wcl; + HWND hwnd; + GIOChannel *windows_messages_channel; #endif nkiddies = (argc == 1 ? 1 : atoi(argv[1])); seqtab = g_malloc (nkiddies * 2 * sizeof (int)); +#ifdef G_OS_WIN32 + wcl.style = 0; + wcl.lpfnWndProc = window_procedure; + wcl.cbClsExtra = 0; + wcl.cbWndExtra = 0; + wcl.hInstance = GetModuleHandle (NULL); + wcl.hIcon = NULL; + wcl.hCursor = NULL; + wcl.hbrBackground = NULL; + wcl.lpszMenuName = NULL; + wcl.lpszClassName = "gio-test"; + + klass = RegisterClass (&wcl); + + if (!klass) + { + g_print ("gio-test: RegisterClass failed\n"); + exit (1); + } + + hwnd = CreateWindow (MAKEINTATOM(klass), "gio-test", 0, 0, 0, 10, 10, + NULL, NULL, wcl.hInstance, NULL); + if (!hwnd) + { + g_print ("gio-test: CreateWindow failed\n"); + exit (1); + } + + windows_messages_channel = g_io_channel_win32_new_messages ((guint)hwnd); + g_io_add_watch (windows_messages_channel, G_IO_IN, recv_windows_message, 0); +#endif + for (i = 0; i < nkiddies; i++) { int pipe_to_sub[2], pipe_from_sub[2]; @@ -199,7 +316,6 @@ main (int argc, pipe (pipe_from_sub) == -1) perror ("pipe"), exit (1); - seqtab[i].fd = pipe_from_sub[0]; seqtab[i].seq = 0; @@ -212,54 +328,68 @@ main (int argc, recv_message, id); - cmdline = g_strdup_printf ("%s %d %d &", argv[0], - pipe_to_sub[0], pipe_from_sub[1]); - nrunning++; #ifdef G_OS_WIN32 - { - gchar *readfd = g_strdup_printf ("%d", pipe_to_sub[0]); - gchar *writefd = g_strdup_printf ("%d", pipe_from_sub[1]); - _spawnl (_P_NOWAIT, argv[0], argv[0], readfd, writefd, NULL); - } + cmdline = g_strdup_printf ("%d:%d:%d", + pipe_to_sub[0], + pipe_from_sub[1], + hwnd); + _spawnl (_P_NOWAIT, argv[0], argv[0], "--child", cmdline, NULL); #else + cmdline = g_strdup_printf ("%s --child %d:%d &", argv[0], + pipe_to_sub[0], pipe_from_sub[1]); + system (cmdline); + g_free (cmdline); #endif close (pipe_to_sub[0]); close (pipe_from_sub [1]); #ifdef G_OS_WIN32 g_get_current_time (&start); - pollresult = g_io_channel_win32_wait_for_condition (my_read_channel, G_IO_IN, 100); + g_io_channel_win32_make_pollfd (my_read_channel, G_IO_IN, &pollfd); + pollresult = g_io_channel_win32_poll (&pollfd, 1, 100); g_get_current_time (&end); if (end.tv_usec < start.tv_usec) end.tv_sec--, end.tv_usec += 1000000; - g_print ("testgio: had to wait %ld.%03ld s, result:%d\n", + g_print ("gio-test: had to wait %ld.%03ld s, result:%d\n", end.tv_sec - start.tv_sec, (end.tv_usec - start.tv_usec) / 1000, pollresult); #endif + g_io_channel_unref (my_read_channel); } - main_loop = g_main_new (FALSE); + main_loop = g_main_loop_new (NULL, FALSE); - g_main_run (main_loop); + g_main_loop_run (main_loop); + + g_main_loop_unref (main_loop); + g_free (seqtab); + g_free (id); } else if (argc == 3) { /* Child */ int readfd, writefd; +#ifdef G_OS_WIN32 + HWND hwnd; +#endif int i, j; char buf[BUFSIZE]; int buflen; GTimeVal tv; + int n; g_get_current_time (&tv); - readfd = atoi (argv[1]); - writefd = atoi (argv[2]); + sscanf (argv[2], "%d:%d%n", &readfd, &writefd, &n); + +#ifdef G_OS_WIN32 + sscanf (argv[2] + n, ":%d", &hwnd); +#endif srand (tv.tv_sec ^ (tv.tv_usec / 1000) ^ readfd ^ (writefd << 4)); @@ -269,12 +399,29 @@ main (int argc, buflen = rand() % BUFSIZE; for (j = 0; j < buflen; j++) buf[j] = ' ' + ((buflen + j) % 95); - g_print ("testgio: child writing %d bytes to %d\n", buflen, writefd); +#ifdef VERBOSE + g_print ("gio-test: child writing %d+%d bytes to %d\n", + (int)(sizeof(i) + sizeof(buflen)), buflen, writefd); +#endif write (writefd, &i, sizeof (i)); write (writefd, &buflen, sizeof (buflen)); write (writefd, buf, buflen); + +#ifdef G_OS_WIN32 + if (rand() % 100 < 5) + { + int msg = WM_USER + (rand() % 100); + WPARAM wparam = rand (); + LPARAM lparam = rand (); + g_print ("gio-test: child posting message %d,%d,%d to %#x\n", + msg, wparam, lparam, hwnd); + PostMessage (hwnd, msg, wparam, lparam); + } +#endif } - g_print ("testgio: child exiting, closing %d\n", writefd); +#ifdef VERBOSE + g_print ("gio-test: child exiting, closing %d\n", writefd); +#endif close (writefd); } else