From 1860151db04ba6232e1f2f06aedf7891d371918f Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Sun, 30 Jul 2000 00:27:39 +0000 Subject: [PATCH] Compile in the debugging code all the time, but only output debug messages 2000-07-30 Tor Lillqvist * giowin32.c: Compile in the debugging code all the time, but only output debug messages if told so. Add (unadvertised) function to turn on/off debug messages for a channel. (buffer_read): Don't loop. It is expected behaviour to return a short read occasionally, for instance when reading from pipes. It's the calling code that should loop if it *knows* how much the writer has written. * tests/gio-test.c: Correct the program's name in the output. (recv_message): Loop calling g_io_channel_read() (in a new function read_all()) until we have all the bytes we want (that we know the writer has written/will write). --- ChangeLog | 16 ++++ ChangeLog.pre-2-0 | 16 ++++ ChangeLog.pre-2-10 | 16 ++++ ChangeLog.pre-2-12 | 16 ++++ ChangeLog.pre-2-2 | 16 ++++ ChangeLog.pre-2-4 | 16 ++++ ChangeLog.pre-2-6 | 16 ++++ ChangeLog.pre-2-8 | 16 ++++ giowin32.c | 204 ++++++++++++++++++++++++++------------------- glib.def | 1 + glib/giowin32.c | 204 ++++++++++++++++++++++++++------------------- glib/glib.def | 1 + tests/gio-test.c | 97 +++++++++++++-------- 13 files changed, 423 insertions(+), 212 deletions(-) diff --git a/ChangeLog b/ChangeLog index aac6ab228..b77004ddf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -42,6 +42,22 @@ * tests/Makefile.am * tests/makefile.mingw.in: Add it. + (Later the same night:) + + * giowin32.c: Compile in the debugging code all the time, but only + output debug messages if told so. Add (unadvertised) function to + turn on/off debug messages for a channel. + + (buffer_read): Don't loop. It is expected behaviour to return a + short read occasionally, for instance when reading from + pipes. It's the calling code that should loop if it *knows* how + much the writer has written. + + * tests/gio-test.c: Correct the program's name in the output. + (recv_message): Loop calling g_io_channel_read() (in a new + function read_all()) until we have all the bytes we want (that we + know the writer has written/will write). + Thu Jul 27 05:15:11 2000 Tim Janik * gstrfuncs.c (g_strlcpy, g_strlcat): completed tor's fix diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index aac6ab228..b77004ddf 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -42,6 +42,22 @@ * tests/Makefile.am * tests/makefile.mingw.in: Add it. + (Later the same night:) + + * giowin32.c: Compile in the debugging code all the time, but only + output debug messages if told so. Add (unadvertised) function to + turn on/off debug messages for a channel. + + (buffer_read): Don't loop. It is expected behaviour to return a + short read occasionally, for instance when reading from + pipes. It's the calling code that should loop if it *knows* how + much the writer has written. + + * tests/gio-test.c: Correct the program's name in the output. + (recv_message): Loop calling g_io_channel_read() (in a new + function read_all()) until we have all the bytes we want (that we + know the writer has written/will write). + Thu Jul 27 05:15:11 2000 Tim Janik * gstrfuncs.c (g_strlcpy, g_strlcat): completed tor's fix diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index aac6ab228..b77004ddf 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -42,6 +42,22 @@ * tests/Makefile.am * tests/makefile.mingw.in: Add it. + (Later the same night:) + + * giowin32.c: Compile in the debugging code all the time, but only + output debug messages if told so. Add (unadvertised) function to + turn on/off debug messages for a channel. + + (buffer_read): Don't loop. It is expected behaviour to return a + short read occasionally, for instance when reading from + pipes. It's the calling code that should loop if it *knows* how + much the writer has written. + + * tests/gio-test.c: Correct the program's name in the output. + (recv_message): Loop calling g_io_channel_read() (in a new + function read_all()) until we have all the bytes we want (that we + know the writer has written/will write). + Thu Jul 27 05:15:11 2000 Tim Janik * gstrfuncs.c (g_strlcpy, g_strlcat): completed tor's fix diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index aac6ab228..b77004ddf 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -42,6 +42,22 @@ * tests/Makefile.am * tests/makefile.mingw.in: Add it. + (Later the same night:) + + * giowin32.c: Compile in the debugging code all the time, but only + output debug messages if told so. Add (unadvertised) function to + turn on/off debug messages for a channel. + + (buffer_read): Don't loop. It is expected behaviour to return a + short read occasionally, for instance when reading from + pipes. It's the calling code that should loop if it *knows* how + much the writer has written. + + * tests/gio-test.c: Correct the program's name in the output. + (recv_message): Loop calling g_io_channel_read() (in a new + function read_all()) until we have all the bytes we want (that we + know the writer has written/will write). + Thu Jul 27 05:15:11 2000 Tim Janik * gstrfuncs.c (g_strlcpy, g_strlcat): completed tor's fix diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index aac6ab228..b77004ddf 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -42,6 +42,22 @@ * tests/Makefile.am * tests/makefile.mingw.in: Add it. + (Later the same night:) + + * giowin32.c: Compile in the debugging code all the time, but only + output debug messages if told so. Add (unadvertised) function to + turn on/off debug messages for a channel. + + (buffer_read): Don't loop. It is expected behaviour to return a + short read occasionally, for instance when reading from + pipes. It's the calling code that should loop if it *knows* how + much the writer has written. + + * tests/gio-test.c: Correct the program's name in the output. + (recv_message): Loop calling g_io_channel_read() (in a new + function read_all()) until we have all the bytes we want (that we + know the writer has written/will write). + Thu Jul 27 05:15:11 2000 Tim Janik * gstrfuncs.c (g_strlcpy, g_strlcat): completed tor's fix diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index aac6ab228..b77004ddf 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -42,6 +42,22 @@ * tests/Makefile.am * tests/makefile.mingw.in: Add it. + (Later the same night:) + + * giowin32.c: Compile in the debugging code all the time, but only + output debug messages if told so. Add (unadvertised) function to + turn on/off debug messages for a channel. + + (buffer_read): Don't loop. It is expected behaviour to return a + short read occasionally, for instance when reading from + pipes. It's the calling code that should loop if it *knows* how + much the writer has written. + + * tests/gio-test.c: Correct the program's name in the output. + (recv_message): Loop calling g_io_channel_read() (in a new + function read_all()) until we have all the bytes we want (that we + know the writer has written/will write). + Thu Jul 27 05:15:11 2000 Tim Janik * gstrfuncs.c (g_strlcpy, g_strlcat): completed tor's fix diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index aac6ab228..b77004ddf 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -42,6 +42,22 @@ * tests/Makefile.am * tests/makefile.mingw.in: Add it. + (Later the same night:) + + * giowin32.c: Compile in the debugging code all the time, but only + output debug messages if told so. Add (unadvertised) function to + turn on/off debug messages for a channel. + + (buffer_read): Don't loop. It is expected behaviour to return a + short read occasionally, for instance when reading from + pipes. It's the calling code that should loop if it *knows* how + much the writer has written. + + * tests/gio-test.c: Correct the program's name in the output. + (recv_message): Loop calling g_io_channel_read() (in a new + function read_all()) until we have all the bytes we want (that we + know the writer has written/will write). + Thu Jul 27 05:15:11 2000 Tim Janik * gstrfuncs.c (g_strlcpy, g_strlcat): completed tor's fix diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index aac6ab228..b77004ddf 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -42,6 +42,22 @@ * tests/Makefile.am * tests/makefile.mingw.in: Add it. + (Later the same night:) + + * giowin32.c: Compile in the debugging code all the time, but only + output debug messages if told so. Add (unadvertised) function to + turn on/off debug messages for a channel. + + (buffer_read): Don't loop. It is expected behaviour to return a + short read occasionally, for instance when reading from + pipes. It's the calling code that should loop if it *knows* how + much the writer has written. + + * tests/gio-test.c: Correct the program's name in the output. + (recv_message): Loop calling g_io_channel_read() (in a new + function read_all()) until we have all the bytes we want (that we + know the writer has written/will write). + Thu Jul 27 05:15:11 2000 Tim Janik * gstrfuncs.c (g_strlcpy, g_strlcat): completed tor's fix diff --git a/giowin32.c b/giowin32.c index c06df4a0d..3d6443143 100644 --- a/giowin32.c +++ b/giowin32.c @@ -28,7 +28,7 @@ * GLib at ftp://ftp.gtk.org/pub/gtk/. */ -/* Define this to get (very) verbose logging */ +/* Define this to get (very) verbose logging of all channels */ /* #define G_IO_WIN32_DEBUG */ #include "glib.h" @@ -66,6 +66,8 @@ struct _GIOWin32Channel { */ GIOWin32ChannelType type; + gboolean debug; + /* This is used by G_IO_WINDOWS_MESSAGES channels */ HWND hwnd; /* handle of window, or NULL */ @@ -99,15 +101,6 @@ struct _GIOWin32Channel { #define LOCK(mutex) EnterCriticalSection (&mutex) #define UNLOCK(mutex) LeaveCriticalSection (&mutex) -/* Temporarilyu change a PRINT to PRINT_ to get just *that* message */ -#define PRINT_(x) g_print x - -#ifdef G_IO_WIN32_DEBUG -#define PRINT(x) PRINT_(x) -#else -#define PRINT(x) -#endif - struct _GIOWin32Watch { GPollFD pollfd; GIOChannel *channel; @@ -115,6 +108,22 @@ struct _GIOWin32Watch { GIOFunc callback; }; +static void +g_io_channel_win32_init (GIOWin32Channel *channel) +{ +#ifdef G_IO_WIN32_DEBUG + channel->debug = TRUE; +#else + if (getenv ("G_IO_WIN32_DEBUG") != NULL) + channel->debug = TRUE; + else + channel->debug = FALSE; +#endif + channel->buffer = NULL; + channel->running = FALSE; + channel->thread_id = 0; +} + static void create_events (GIOWin32Channel *channel) { @@ -148,12 +157,13 @@ reader_thread (void *parameter) g_io_channel_ref ((GIOChannel *) channel); - PRINT (("thread %#x: starting. pid:%#x, fd:%d, data_avail:%#x, space_avail:%#x\n", - channel->thread_id, - (guint) GetCurrentProcessId (), - channel->fd, - (guint) channel->data_avail_event, - (guint) channel->space_avail_event)); + if (channel->debug) + g_print ("thread %#x: starting. pid:%#x, fd:%d, data_avail:%#x, space_avail:%#x\n", + channel->thread_id, + (guint) GetCurrentProcessId (), + channel->fd, + (guint) channel->data_avail_event, + (guint) channel->space_avail_event); channel->buffer = g_malloc (BUFFER_SIZE); channel->rdp = channel->wrp = 0; @@ -164,20 +174,24 @@ reader_thread (void *parameter) while (channel->running) { LOCK (channel->mutex); - PRINT (("thread %#x: rdp=%d, wrp=%d\n", - channel->thread_id, channel->rdp, channel->wrp)); + if (channel->debug) + g_print ("thread %#x: rdp=%d, wrp=%d\n", + channel->thread_id, channel->rdp, channel->wrp); if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp) { /* Buffer is full */ - PRINT (("thread %#x: resetting space_available\n", - channel->thread_id)); + if (channel->debug) + g_print ("thread %#x: resetting space_available\n", + channel->thread_id); ResetEvent (channel->space_avail_event); - PRINT (("thread %#x: waiting for space\n", channel->thread_id)); + if (channel->debug) + g_print ("thread %#x: waiting for space\n", channel->thread_id); UNLOCK (channel->mutex); WaitForSingleObject (channel->space_avail_event, INFINITE); LOCK (channel->mutex); - PRINT (("thread %#x: rdp=%d, wrp=%d\n", - channel->thread_id, channel->rdp, channel->wrp)); + if (channel->debug) + g_print ("thread %#x: rdp=%d, wrp=%d\n", + channel->thread_id, channel->rdp, channel->wrp); } buffer = channel->buffer + channel->wrp; @@ -196,19 +210,22 @@ reader_thread (void *parameter) break; LOCK (channel->mutex); - PRINT (("thread %#x: got %d bytes, rdp=%d, wrp=%d\n", - channel->thread_id, nbytes, channel->rdp, channel->wrp)); + if (channel->debug) + g_print ("thread %#x: got %d bytes, rdp=%d, wrp=%d\n", + channel->thread_id, nbytes, channel->rdp, channel->wrp); channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE; - PRINT (("thread %#x: rdp=%d, wrp=%d, setting data available\n", - channel->thread_id, channel->rdp, channel->wrp)); + if (channel->debug) + g_print ("thread %#x: rdp=%d, wrp=%d, setting data available\n", + channel->thread_id, channel->rdp, channel->wrp); SetEvent (channel->data_avail_event); UNLOCK (channel->mutex); } LOCK (channel->mutex); channel->running = FALSE; - PRINT (("thread %#x: got EOF, rdp=%d, wrp=%d, setting data available\n", - channel->thread_id, channel->rdp, channel->wrp)); + if (channel->debug) + g_print ("thread %#x: got EOF, rdp=%d, wrp=%d, setting data available\n", + channel->thread_id, channel->rdp, channel->wrp); SetEvent (channel->data_avail_event); UNLOCK (channel->mutex); @@ -244,47 +261,54 @@ buffer_read (GIOWin32Channel *channel, guint left = count; LOCK (channel->mutex); - PRINT (("reading from thread %#x %d bytes, rdp=%d, wrp=%d\n", - channel->thread_id, count, channel->rdp, channel->wrp)); + if (channel->debug) + g_print ("reading from thread %#x %d bytes, rdp=%d, wrp=%d\n", + channel->thread_id, count, channel->rdp, channel->wrp); - while (left) + if (channel->rdp == channel->wrp) { - if (channel->rdp == channel->wrp) - { - UNLOCK (channel->mutex); - PRINT (("waiting for data from thread %#x\n", channel->thread_id)); - WaitForSingleObject (channel->data_avail_event, INFINITE); - LOCK (channel->mutex); - if (channel->rdp == channel->wrp && !channel->running) - break; - } - - if (channel->rdp < channel->wrp) - nbytes = channel->wrp - channel->rdp; - else - nbytes = BUFFER_SIZE - channel->rdp; UNLOCK (channel->mutex); - nbytes = MIN (left, nbytes); - PRINT (("moving %d bytes from thread %#x\n", - nbytes, channel->thread_id)); - memcpy (dest, channel->buffer + channel->rdp, nbytes); - dest += nbytes; - left -= nbytes; + if (channel->debug) + g_print ("waiting for data from thread %#x\n", channel->thread_id); + WaitForSingleObject (channel->data_avail_event, INFINITE); LOCK (channel->mutex); - channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE; - PRINT (("setting space available for thread %#x\n", channel->thread_id)); - SetEvent (channel->space_avail_event); - PRINT (("for thread %#x: rdp=%d, wrp=%d\n", - channel->thread_id, channel->rdp, channel->wrp)); - if (channel->running && channel->rdp == channel->wrp) - { - PRINT (("resetting data_available of thread %#x\n", - channel->thread_id)); - ResetEvent (channel->data_avail_event); - }; + if (channel->rdp == channel->wrp && !channel->running) + break; } + + if (channel->rdp < channel->wrp) + nbytes = channel->wrp - channel->rdp; + else + nbytes = BUFFER_SIZE - channel->rdp; + UNLOCK (channel->mutex); + nbytes = MIN (left, nbytes); + if (channel->debug) + g_print ("moving %d bytes from thread %#x\n", + nbytes, channel->thread_id); + memcpy (dest, channel->buffer + channel->rdp, nbytes); + dest += nbytes; + left -= nbytes; + LOCK (channel->mutex); + channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE; + if (channel->debug) + g_print ("setting space available for thread %#x\n", channel->thread_id); + SetEvent (channel->space_avail_event); + if (channel->debug) + g_print ("for thread %#x: rdp=%d, wrp=%d\n", + channel->thread_id, channel->rdp, channel->wrp); + if (channel->running && channel->rdp == channel->wrp) + { + if (channel->debug) + g_print ("resetting data_available of thread %#x\n", + channel->thread_id); + ResetEvent (channel->data_avail_event); + }; UNLOCK (channel->mutex); + /* We have no way to indicate any errors form the actual + * read() or recv() call in the reader thread. Should we have? + */ + *error = G_IO_ERROR_NONE; return count - left; } @@ -312,7 +336,9 @@ g_io_win32_check (gpointer source_data, */ if (!channel->running && channel->rdp == channel->wrp) { - PRINT (("g_io_win32_check: setting G_IO_HUP thread %#x rdp=%d wrp=%d\n", channel->thread_id, channel->rdp, channel->wrp)); + if (channel->debug) + g_print ("g_io_win32_check: setting G_IO_HUP thread %#x rdp=%d wrp=%d\n", + channel->thread_id, channel->rdp, channel->wrp); data->pollfd.revents |= G_IO_HUP; return TRUE; } @@ -499,7 +525,9 @@ g_io_win32_fd_write(GIOChannel *channel, gint result; result = write (win32_channel->fd, buf, count); - PRINT (("g_io_win32_fd_write: fd:%d count:%d = %d\n", win32_channel->fd, count, result)); + if (win32_channel->debug) + g_print ("g_io_win32_fd_write: fd:%d count:%d = %d\n", + win32_channel->fd, count, result); if (result < 0) { @@ -576,13 +604,7 @@ fd_reader (int fd, guchar *buf, int len) { - int value; - - value = read (fd, buf, len); - - PRINT (("fd_reader (%d,%p,%d) = %d\n", fd, buf, len, value)); - - return value; + return read (fd, buf, len); } static guint @@ -609,8 +631,9 @@ g_io_win32_fd_add_watch (GIOChannel *channel, watch->pollfd.fd = (gint) win32_channel->data_avail_event; watch->pollfd.events = condition; - PRINT (("g_io_win32_fd_add_watch: fd:%d handle:%#x\n", - win32_channel->fd, watch->pollfd.fd)); + if (win32_channel->debug) + g_print ("g_io_win32_fd_add_watch: fd:%d handle:%#x\n", + win32_channel->fd, watch->pollfd.fd); /* Is it readable? (Would be strange to watch it otherwise, but... */ if (ReadFile ((HANDLE) _get_osfhandle (win32_channel->fd), @@ -775,6 +798,7 @@ g_io_channel_win32_new_messages (guint hwnd) GIOChannel *channel = (GIOChannel *) win32_channel; g_io_channel_init (channel); + g_io_channel_win32_init (win32_channel); channel->funcs = &win32_channel_msg_funcs; win32_channel->type = G_IO_WINDOWS_MESSAGES; win32_channel->hwnd = (HWND) hwnd; @@ -795,19 +819,14 @@ g_io_channel_win32_new_fd (gint fd) return NULL; } - PRINT (("g_io_channel_win32_new_fd: %d\n", fd)); - win32_channel = g_new (GIOWin32Channel, 1); channel = (GIOChannel *) win32_channel; g_io_channel_init (channel); - + g_io_channel_win32_init (win32_channel); channel->funcs = &win32_channel_fd_funcs; - win32_channel->fd = fd; win32_channel->type = G_IO_FILE_DESC; - win32_channel->buffer = NULL; - win32_channel->running = FALSE; - win32_channel->thread_id = 0; + win32_channel->fd = fd; return channel; } @@ -827,12 +846,10 @@ g_io_channel_win32_new_stream_socket (int socket) GIOChannel *channel = (GIOChannel *) win32_channel; g_io_channel_init (channel); + g_io_channel_win32_init (win32_channel); channel->funcs = &win32_channel_sock_funcs; - win32_channel->fd = socket; win32_channel->type = G_IO_STREAM_SOCKET; - win32_channel->buffer = NULL; - win32_channel->running = FALSE; - win32_channel->thread_id = 0; + win32_channel->fd = socket; return channel; } @@ -849,6 +866,15 @@ g_io_channel_unix_get_fd (GIOChannel *channel) return g_io_channel_win32_get_fd (channel); } +void +g_io_channel_win32_set_debug (GIOChannel *channel, + gboolean flag) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel; + + win32_channel->debug = flag; +} + gint g_io_channel_win32_wait_for_condition (GIOChannel *channel, GIOCondition condition, @@ -861,12 +887,14 @@ g_io_channel_win32_wait_for_condition (GIOChannel *channel, pollfd.fd = (gint) win32_channel->data_avail_event; pollfd.events = condition; - PRINT (("g_io_channel_win32_wait_for_condition: fd:%d event:%#x timeout:%d\n", - win32_channel->fd, pollfd.fd, timeout)); + if (win32_channel->debug) + g_print ("g_io_channel_win32_wait_for_condition: fd:%d event:%#x timeout:%d\n", + win32_channel->fd, pollfd.fd, timeout); result = (*g_main_win32_get_poll_func ()) (&pollfd, 1, timeout); - PRINT (("g_io_channel_win32_wait_for_condition: done:%d\n", result)); + if (win32_channel->debug) + g_print ("g_io_channel_win32_wait_for_condition: done:%d\n", result); return result; } diff --git a/glib.def b/glib.def index 9e1b56ca1..2781cb487 100644 --- a/glib.def +++ b/glib.def @@ -166,6 +166,7 @@ EXPORTS g_io_channel_win32_new_stream_socket g_io_channel_win32_pipe_readable g_io_channel_win32_pipe_request_wakeups + g_io_channel_win32_set_debug g_io_channel_win32_wait_for_condition g_io_channel_write g_list_alloc diff --git a/glib/giowin32.c b/glib/giowin32.c index c06df4a0d..3d6443143 100644 --- a/glib/giowin32.c +++ b/glib/giowin32.c @@ -28,7 +28,7 @@ * GLib at ftp://ftp.gtk.org/pub/gtk/. */ -/* Define this to get (very) verbose logging */ +/* Define this to get (very) verbose logging of all channels */ /* #define G_IO_WIN32_DEBUG */ #include "glib.h" @@ -66,6 +66,8 @@ struct _GIOWin32Channel { */ GIOWin32ChannelType type; + gboolean debug; + /* This is used by G_IO_WINDOWS_MESSAGES channels */ HWND hwnd; /* handle of window, or NULL */ @@ -99,15 +101,6 @@ struct _GIOWin32Channel { #define LOCK(mutex) EnterCriticalSection (&mutex) #define UNLOCK(mutex) LeaveCriticalSection (&mutex) -/* Temporarilyu change a PRINT to PRINT_ to get just *that* message */ -#define PRINT_(x) g_print x - -#ifdef G_IO_WIN32_DEBUG -#define PRINT(x) PRINT_(x) -#else -#define PRINT(x) -#endif - struct _GIOWin32Watch { GPollFD pollfd; GIOChannel *channel; @@ -115,6 +108,22 @@ struct _GIOWin32Watch { GIOFunc callback; }; +static void +g_io_channel_win32_init (GIOWin32Channel *channel) +{ +#ifdef G_IO_WIN32_DEBUG + channel->debug = TRUE; +#else + if (getenv ("G_IO_WIN32_DEBUG") != NULL) + channel->debug = TRUE; + else + channel->debug = FALSE; +#endif + channel->buffer = NULL; + channel->running = FALSE; + channel->thread_id = 0; +} + static void create_events (GIOWin32Channel *channel) { @@ -148,12 +157,13 @@ reader_thread (void *parameter) g_io_channel_ref ((GIOChannel *) channel); - PRINT (("thread %#x: starting. pid:%#x, fd:%d, data_avail:%#x, space_avail:%#x\n", - channel->thread_id, - (guint) GetCurrentProcessId (), - channel->fd, - (guint) channel->data_avail_event, - (guint) channel->space_avail_event)); + if (channel->debug) + g_print ("thread %#x: starting. pid:%#x, fd:%d, data_avail:%#x, space_avail:%#x\n", + channel->thread_id, + (guint) GetCurrentProcessId (), + channel->fd, + (guint) channel->data_avail_event, + (guint) channel->space_avail_event); channel->buffer = g_malloc (BUFFER_SIZE); channel->rdp = channel->wrp = 0; @@ -164,20 +174,24 @@ reader_thread (void *parameter) while (channel->running) { LOCK (channel->mutex); - PRINT (("thread %#x: rdp=%d, wrp=%d\n", - channel->thread_id, channel->rdp, channel->wrp)); + if (channel->debug) + g_print ("thread %#x: rdp=%d, wrp=%d\n", + channel->thread_id, channel->rdp, channel->wrp); if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp) { /* Buffer is full */ - PRINT (("thread %#x: resetting space_available\n", - channel->thread_id)); + if (channel->debug) + g_print ("thread %#x: resetting space_available\n", + channel->thread_id); ResetEvent (channel->space_avail_event); - PRINT (("thread %#x: waiting for space\n", channel->thread_id)); + if (channel->debug) + g_print ("thread %#x: waiting for space\n", channel->thread_id); UNLOCK (channel->mutex); WaitForSingleObject (channel->space_avail_event, INFINITE); LOCK (channel->mutex); - PRINT (("thread %#x: rdp=%d, wrp=%d\n", - channel->thread_id, channel->rdp, channel->wrp)); + if (channel->debug) + g_print ("thread %#x: rdp=%d, wrp=%d\n", + channel->thread_id, channel->rdp, channel->wrp); } buffer = channel->buffer + channel->wrp; @@ -196,19 +210,22 @@ reader_thread (void *parameter) break; LOCK (channel->mutex); - PRINT (("thread %#x: got %d bytes, rdp=%d, wrp=%d\n", - channel->thread_id, nbytes, channel->rdp, channel->wrp)); + if (channel->debug) + g_print ("thread %#x: got %d bytes, rdp=%d, wrp=%d\n", + channel->thread_id, nbytes, channel->rdp, channel->wrp); channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE; - PRINT (("thread %#x: rdp=%d, wrp=%d, setting data available\n", - channel->thread_id, channel->rdp, channel->wrp)); + if (channel->debug) + g_print ("thread %#x: rdp=%d, wrp=%d, setting data available\n", + channel->thread_id, channel->rdp, channel->wrp); SetEvent (channel->data_avail_event); UNLOCK (channel->mutex); } LOCK (channel->mutex); channel->running = FALSE; - PRINT (("thread %#x: got EOF, rdp=%d, wrp=%d, setting data available\n", - channel->thread_id, channel->rdp, channel->wrp)); + if (channel->debug) + g_print ("thread %#x: got EOF, rdp=%d, wrp=%d, setting data available\n", + channel->thread_id, channel->rdp, channel->wrp); SetEvent (channel->data_avail_event); UNLOCK (channel->mutex); @@ -244,47 +261,54 @@ buffer_read (GIOWin32Channel *channel, guint left = count; LOCK (channel->mutex); - PRINT (("reading from thread %#x %d bytes, rdp=%d, wrp=%d\n", - channel->thread_id, count, channel->rdp, channel->wrp)); + if (channel->debug) + g_print ("reading from thread %#x %d bytes, rdp=%d, wrp=%d\n", + channel->thread_id, count, channel->rdp, channel->wrp); - while (left) + if (channel->rdp == channel->wrp) { - if (channel->rdp == channel->wrp) - { - UNLOCK (channel->mutex); - PRINT (("waiting for data from thread %#x\n", channel->thread_id)); - WaitForSingleObject (channel->data_avail_event, INFINITE); - LOCK (channel->mutex); - if (channel->rdp == channel->wrp && !channel->running) - break; - } - - if (channel->rdp < channel->wrp) - nbytes = channel->wrp - channel->rdp; - else - nbytes = BUFFER_SIZE - channel->rdp; UNLOCK (channel->mutex); - nbytes = MIN (left, nbytes); - PRINT (("moving %d bytes from thread %#x\n", - nbytes, channel->thread_id)); - memcpy (dest, channel->buffer + channel->rdp, nbytes); - dest += nbytes; - left -= nbytes; + if (channel->debug) + g_print ("waiting for data from thread %#x\n", channel->thread_id); + WaitForSingleObject (channel->data_avail_event, INFINITE); LOCK (channel->mutex); - channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE; - PRINT (("setting space available for thread %#x\n", channel->thread_id)); - SetEvent (channel->space_avail_event); - PRINT (("for thread %#x: rdp=%d, wrp=%d\n", - channel->thread_id, channel->rdp, channel->wrp)); - if (channel->running && channel->rdp == channel->wrp) - { - PRINT (("resetting data_available of thread %#x\n", - channel->thread_id)); - ResetEvent (channel->data_avail_event); - }; + if (channel->rdp == channel->wrp && !channel->running) + break; } + + if (channel->rdp < channel->wrp) + nbytes = channel->wrp - channel->rdp; + else + nbytes = BUFFER_SIZE - channel->rdp; + UNLOCK (channel->mutex); + nbytes = MIN (left, nbytes); + if (channel->debug) + g_print ("moving %d bytes from thread %#x\n", + nbytes, channel->thread_id); + memcpy (dest, channel->buffer + channel->rdp, nbytes); + dest += nbytes; + left -= nbytes; + LOCK (channel->mutex); + channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE; + if (channel->debug) + g_print ("setting space available for thread %#x\n", channel->thread_id); + SetEvent (channel->space_avail_event); + if (channel->debug) + g_print ("for thread %#x: rdp=%d, wrp=%d\n", + channel->thread_id, channel->rdp, channel->wrp); + if (channel->running && channel->rdp == channel->wrp) + { + if (channel->debug) + g_print ("resetting data_available of thread %#x\n", + channel->thread_id); + ResetEvent (channel->data_avail_event); + }; UNLOCK (channel->mutex); + /* We have no way to indicate any errors form the actual + * read() or recv() call in the reader thread. Should we have? + */ + *error = G_IO_ERROR_NONE; return count - left; } @@ -312,7 +336,9 @@ g_io_win32_check (gpointer source_data, */ if (!channel->running && channel->rdp == channel->wrp) { - PRINT (("g_io_win32_check: setting G_IO_HUP thread %#x rdp=%d wrp=%d\n", channel->thread_id, channel->rdp, channel->wrp)); + if (channel->debug) + g_print ("g_io_win32_check: setting G_IO_HUP thread %#x rdp=%d wrp=%d\n", + channel->thread_id, channel->rdp, channel->wrp); data->pollfd.revents |= G_IO_HUP; return TRUE; } @@ -499,7 +525,9 @@ g_io_win32_fd_write(GIOChannel *channel, gint result; result = write (win32_channel->fd, buf, count); - PRINT (("g_io_win32_fd_write: fd:%d count:%d = %d\n", win32_channel->fd, count, result)); + if (win32_channel->debug) + g_print ("g_io_win32_fd_write: fd:%d count:%d = %d\n", + win32_channel->fd, count, result); if (result < 0) { @@ -576,13 +604,7 @@ fd_reader (int fd, guchar *buf, int len) { - int value; - - value = read (fd, buf, len); - - PRINT (("fd_reader (%d,%p,%d) = %d\n", fd, buf, len, value)); - - return value; + return read (fd, buf, len); } static guint @@ -609,8 +631,9 @@ g_io_win32_fd_add_watch (GIOChannel *channel, watch->pollfd.fd = (gint) win32_channel->data_avail_event; watch->pollfd.events = condition; - PRINT (("g_io_win32_fd_add_watch: fd:%d handle:%#x\n", - win32_channel->fd, watch->pollfd.fd)); + if (win32_channel->debug) + g_print ("g_io_win32_fd_add_watch: fd:%d handle:%#x\n", + win32_channel->fd, watch->pollfd.fd); /* Is it readable? (Would be strange to watch it otherwise, but... */ if (ReadFile ((HANDLE) _get_osfhandle (win32_channel->fd), @@ -775,6 +798,7 @@ g_io_channel_win32_new_messages (guint hwnd) GIOChannel *channel = (GIOChannel *) win32_channel; g_io_channel_init (channel); + g_io_channel_win32_init (win32_channel); channel->funcs = &win32_channel_msg_funcs; win32_channel->type = G_IO_WINDOWS_MESSAGES; win32_channel->hwnd = (HWND) hwnd; @@ -795,19 +819,14 @@ g_io_channel_win32_new_fd (gint fd) return NULL; } - PRINT (("g_io_channel_win32_new_fd: %d\n", fd)); - win32_channel = g_new (GIOWin32Channel, 1); channel = (GIOChannel *) win32_channel; g_io_channel_init (channel); - + g_io_channel_win32_init (win32_channel); channel->funcs = &win32_channel_fd_funcs; - win32_channel->fd = fd; win32_channel->type = G_IO_FILE_DESC; - win32_channel->buffer = NULL; - win32_channel->running = FALSE; - win32_channel->thread_id = 0; + win32_channel->fd = fd; return channel; } @@ -827,12 +846,10 @@ g_io_channel_win32_new_stream_socket (int socket) GIOChannel *channel = (GIOChannel *) win32_channel; g_io_channel_init (channel); + g_io_channel_win32_init (win32_channel); channel->funcs = &win32_channel_sock_funcs; - win32_channel->fd = socket; win32_channel->type = G_IO_STREAM_SOCKET; - win32_channel->buffer = NULL; - win32_channel->running = FALSE; - win32_channel->thread_id = 0; + win32_channel->fd = socket; return channel; } @@ -849,6 +866,15 @@ g_io_channel_unix_get_fd (GIOChannel *channel) return g_io_channel_win32_get_fd (channel); } +void +g_io_channel_win32_set_debug (GIOChannel *channel, + gboolean flag) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel; + + win32_channel->debug = flag; +} + gint g_io_channel_win32_wait_for_condition (GIOChannel *channel, GIOCondition condition, @@ -861,12 +887,14 @@ g_io_channel_win32_wait_for_condition (GIOChannel *channel, pollfd.fd = (gint) win32_channel->data_avail_event; pollfd.events = condition; - PRINT (("g_io_channel_win32_wait_for_condition: fd:%d event:%#x timeout:%d\n", - win32_channel->fd, pollfd.fd, timeout)); + if (win32_channel->debug) + g_print ("g_io_channel_win32_wait_for_condition: fd:%d event:%#x timeout:%d\n", + win32_channel->fd, pollfd.fd, timeout); result = (*g_main_win32_get_poll_func ()) (&pollfd, 1, timeout); - PRINT (("g_io_channel_win32_wait_for_condition: done:%d\n", result)); + if (win32_channel->debug) + g_print ("g_io_channel_win32_wait_for_condition: done:%d\n", result); return result; } diff --git a/glib/glib.def b/glib/glib.def index 9e1b56ca1..2781cb487 100644 --- a/glib/glib.def +++ b/glib/glib.def @@ -166,6 +166,7 @@ EXPORTS g_io_channel_win32_new_stream_socket g_io_channel_win32_pipe_readable g_io_channel_win32_pipe_request_wakeups + g_io_channel_win32_set_debug g_io_channel_win32_wait_for_condition g_io_channel_write g_list_alloc diff --git a/tests/gio-test.c b/tests/gio-test.c index cbdbe60ad..0a22e2767 100644 --- a/tests/gio-test.c +++ b/tests/gio-test.c @@ -54,6 +54,46 @@ static struct { int seq; } *seqtab; +static GIOError +read_all (int fd, + GIOChannel *channel, + char *buffer, + guint nbytes, + guint *bytes_read) +{ + guint left = nbytes; + guint nb; + GIOError error; + 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: G_IO_ERROR_%s\n", fd, + (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; + } + if (nb == 0) + return error; + left -= nb; + bufp += nb; + *bytes_read += nb; + } + return error; +} + + static gboolean recv_message (GIOChannel *channel, GIOCondition cond, @@ -61,7 +101,7 @@ recv_message (GIOChannel *channel, { gint fd = g_io_channel_unix_get_fd (channel); - g_print ("testgio: ...from %d:%s%s%s%s\n", fd, + 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" : "", @@ -83,12 +123,12 @@ 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); + g_print ("gio-test: ...from %d: EOF\n", fd); return FALSE; } @@ -99,7 +139,7 @@ recv_message (GIOChannel *channel, { if (seq != seqtab[i].seq) { - g_print ("testgio: ...from &d: invalid sequence number %d, expected %d\n", + g_print ("gio-test: ...from &d: invalid sequence number %d, expected %d\n", seq, seqtab[i].seq); g_assert_not_reached (); } @@ -107,22 +147,15 @@ recv_message (GIOChannel *channel, 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); + g_print ("gio-test: ...from %d: EOF\n", fd); return FALSE; } @@ -130,42 +163,34 @@ recv_message (GIOChannel *channel, if (nbytes >= BUFSIZE) { - g_print ("testgio: ...from %d: nbytes = %d (%#x)!\n", fd, nbytes, nbytes); + g_print ("gio-test: ...from %d: nbytes = %d (%#x)!\n", fd, nbytes, nbytes); g_assert_not_reached (); } g_assert (nbytes >= 0 && nbytes < BUFSIZE); - g_print ("testgio: ...from %d: %d bytes\n", fd, nbytes); + g_print ("gio-test: ...from %d: %d bytes\n", fd, nbytes); 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) + return FALSE; + + if (nb == 0) { - 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" : "???")))); - + g_print ("gio-test: ...from %d: EOF\n", fd); return FALSE; } - - if (nb != nbytes) - { - g_print ("testgio: ...from %d: nb=%d != nbytes=%d\n", - fd, nb, nbytes); - g_assert_not_reached (); - } - + for (j = 0; j < nbytes; j++) if (buf[j] != ' ' + ((nbytes + j) % 95)) { - g_print ("testgio: ...from %d: buf[%d] == '%c', should be '%c'\n", + g_print ("gio-test: ...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_print ("gio-test: ...from %d: OK\n", fd); } } return TRUE; @@ -235,7 +260,7 @@ main (int argc, 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); @@ -269,12 +294,12 @@ 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); + g_print ("gio-test: child writing %d bytes to %d\n", buflen, writefd); write (writefd, &i, sizeof (i)); write (writefd, &buflen, sizeof (buflen)); write (writefd, buf, buflen); } - g_print ("testgio: child exiting, closing %d\n", writefd); + g_print ("gio-test: child exiting, closing %d\n", writefd); close (writefd); } else