Compile in the debugging code all the time, but only output debug messages
authorTor Lillqvist <tml@iki.fi>
Sun, 30 Jul 2000 00:27:39 +0000 (00:27 +0000)
committerTor Lillqvist <tml@src.gnome.org>
Sun, 30 Jul 2000 00:27:39 +0000 (00:27 +0000)
2000-07-30  Tor Lillqvist  <tml@iki.fi>

* 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).

13 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-12
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
giowin32.c
glib.def
glib/giowin32.c
glib/glib.def
tests/gio-test.c

index aac6ab2..b77004d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
        * 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  <timj@gtk.org>
 
        * gstrfuncs.c (g_strlcpy, g_strlcat): completed tor's fix
index aac6ab2..b77004d 100644 (file)
        * 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  <timj@gtk.org>
 
        * gstrfuncs.c (g_strlcpy, g_strlcat): completed tor's fix
index aac6ab2..b77004d 100644 (file)
        * 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  <timj@gtk.org>
 
        * gstrfuncs.c (g_strlcpy, g_strlcat): completed tor's fix
index aac6ab2..b77004d 100644 (file)
        * 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  <timj@gtk.org>
 
        * gstrfuncs.c (g_strlcpy, g_strlcat): completed tor's fix
index aac6ab2..b77004d 100644 (file)
        * 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  <timj@gtk.org>
 
        * gstrfuncs.c (g_strlcpy, g_strlcat): completed tor's fix
index aac6ab2..b77004d 100644 (file)
        * 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  <timj@gtk.org>
 
        * gstrfuncs.c (g_strlcpy, g_strlcat): completed tor's fix
index aac6ab2..b77004d 100644 (file)
        * 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  <timj@gtk.org>
 
        * gstrfuncs.c (g_strlcpy, g_strlcat): completed tor's fix
index aac6ab2..b77004d 100644 (file)
        * 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  <timj@gtk.org>
 
        * gstrfuncs.c (g_strlcpy, g_strlcat): completed tor's fix
index c06df4a..3d64431 100644 (file)
@@ -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;
@@ -116,6 +109,22 @@ struct _GIOWin32Watch {
 };
 
 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)
 {
   SECURITY_ATTRIBUTES sec_attrs;
@@ -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;
 }
index 9e1b56c..2781cb4 100644 (file)
--- 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
index c06df4a..3d64431 100644 (file)
@@ -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;
@@ -116,6 +109,22 @@ struct _GIOWin32Watch {
 };
 
 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)
 {
   SECURITY_ATTRIBUTES sec_attrs;
@@ -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;
 }
index 9e1b56c..2781cb4 100644 (file)
@@ -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
index cbdbe60..0a22e27 100644 (file)
@@ -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)
-           {
-             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 ();
+             g_print ("gio-test: ...from %d: EOF\n", fd);
+             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",
+               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