Get len using strlen() if arg is negative in the Win32 code, too.
authorTor Lillqvist <tml@iki.fi>
Sat, 6 Jan 2001 03:09:46 +0000 (03:09 +0000)
committerTor Lillqvist <tml@src.gnome.org>
Sat, 6 Jan 2001 03:09:46 +0000 (03:09 +0000)
2001-01-06  Tor Lillqvist  <tml@iki.fi>

* gconvert.c (g_locale_to_utf8, g_locale_from_utf8): Get len using
strlen() if arg is negative in the Win32 code, too.

* giowin32.c: Changes necessary to be able to run
mainloop-test. We can't close the fd that our (internal) reader
thread is sitting doing a blocking read() from. We must terminate
the thread first. Keep track of thread handle, and close it when
thread is dying. Start reader thread with the lower-level
CreateThread() instead of _beginthreadex() from the C runtime, in
order to be able to use TerminateThread(). Hopefuly this isn't
harmful.

* glib.def: Update.

* tests/makefile.{mingw,msc}.in (TESTS): Add mainloop-test and
unicode-encoding.

* tests/mainloop-test.c: Portability: <unistd.h>, need <fcntl.h>
on Win32.

* tests/unicode-encoding.c (process): Add missing "line" argument
to fail(). On Win32, convert UTF-16LE, as libiconv'c ivonf always
converts to UTF-16BE if we ask for unspecific UTF-16.
(main) Handle also '\r'.

18 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
gconvert.c
giowin32.c
glib.def
glib/gconvert.c
glib/giowin32.c
glib/glib.def
tests/mainloop-test.c
tests/makefile.mingw.in
tests/makefile.msc.in
tests/unicode-encoding.c

index 6478f6a..0e60410 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2001-01-06  Tor Lillqvist  <tml@iki.fi>
+
+       * gconvert.c (g_locale_to_utf8, g_locale_from_utf8): Get len using
+       strlen() if arg is negative in the Win32 code, too.
+
+       * giowin32.c: Changes necessary to be able to run
+       mainloop-test. We can't close the fd that our (internal) reader
+       thread is sitting doing a blocking read() from. We must terminate
+       the thread first. Keep track of thread handle, and close it when
+       thread is dying. Start reader thread with the lower-level
+       CreateThread() instead of _beginthreadex() from the C runtime, in
+       order to be able to use TerminateThread(). Hopefuly this isn't
+       harmful.
+
+       * glib.def: Update.
+
+       * tests/makefile.{mingw,msc}.in (TESTS): Add mainloop-test and
+       unicode-encoding.
+
+       * tests/mainloop-test.c: Portability: <unistd.h>, need <fcntl.h>
+       on Win32.
+
+       * tests/unicode-encoding.c (process): Add missing "line" argument
+       to fail(). On Win32, convert UTF-16LE, as libiconv'c ivonf always
+       converts to UTF-16BE if we ask for unspecific UTF-16.
+       (main) Handle also '\r'.
+
 Fri Jan  5 11:25:42 2001  Owen Taylor  <otaylor@redhat.com>
 
        * configure.in (PACKAGE): move $enable_debug down below
index 6478f6a..0e60410 100644 (file)
@@ -1,3 +1,30 @@
+2001-01-06  Tor Lillqvist  <tml@iki.fi>
+
+       * gconvert.c (g_locale_to_utf8, g_locale_from_utf8): Get len using
+       strlen() if arg is negative in the Win32 code, too.
+
+       * giowin32.c: Changes necessary to be able to run
+       mainloop-test. We can't close the fd that our (internal) reader
+       thread is sitting doing a blocking read() from. We must terminate
+       the thread first. Keep track of thread handle, and close it when
+       thread is dying. Start reader thread with the lower-level
+       CreateThread() instead of _beginthreadex() from the C runtime, in
+       order to be able to use TerminateThread(). Hopefuly this isn't
+       harmful.
+
+       * glib.def: Update.
+
+       * tests/makefile.{mingw,msc}.in (TESTS): Add mainloop-test and
+       unicode-encoding.
+
+       * tests/mainloop-test.c: Portability: <unistd.h>, need <fcntl.h>
+       on Win32.
+
+       * tests/unicode-encoding.c (process): Add missing "line" argument
+       to fail(). On Win32, convert UTF-16LE, as libiconv'c ivonf always
+       converts to UTF-16BE if we ask for unspecific UTF-16.
+       (main) Handle also '\r'.
+
 Fri Jan  5 11:25:42 2001  Owen Taylor  <otaylor@redhat.com>
 
        * configure.in (PACKAGE): move $enable_debug down below
index 6478f6a..0e60410 100644 (file)
@@ -1,3 +1,30 @@
+2001-01-06  Tor Lillqvist  <tml@iki.fi>
+
+       * gconvert.c (g_locale_to_utf8, g_locale_from_utf8): Get len using
+       strlen() if arg is negative in the Win32 code, too.
+
+       * giowin32.c: Changes necessary to be able to run
+       mainloop-test. We can't close the fd that our (internal) reader
+       thread is sitting doing a blocking read() from. We must terminate
+       the thread first. Keep track of thread handle, and close it when
+       thread is dying. Start reader thread with the lower-level
+       CreateThread() instead of _beginthreadex() from the C runtime, in
+       order to be able to use TerminateThread(). Hopefuly this isn't
+       harmful.
+
+       * glib.def: Update.
+
+       * tests/makefile.{mingw,msc}.in (TESTS): Add mainloop-test and
+       unicode-encoding.
+
+       * tests/mainloop-test.c: Portability: <unistd.h>, need <fcntl.h>
+       on Win32.
+
+       * tests/unicode-encoding.c (process): Add missing "line" argument
+       to fail(). On Win32, convert UTF-16LE, as libiconv'c ivonf always
+       converts to UTF-16BE if we ask for unspecific UTF-16.
+       (main) Handle also '\r'.
+
 Fri Jan  5 11:25:42 2001  Owen Taylor  <otaylor@redhat.com>
 
        * configure.in (PACKAGE): move $enable_debug down below
index 6478f6a..0e60410 100644 (file)
@@ -1,3 +1,30 @@
+2001-01-06  Tor Lillqvist  <tml@iki.fi>
+
+       * gconvert.c (g_locale_to_utf8, g_locale_from_utf8): Get len using
+       strlen() if arg is negative in the Win32 code, too.
+
+       * giowin32.c: Changes necessary to be able to run
+       mainloop-test. We can't close the fd that our (internal) reader
+       thread is sitting doing a blocking read() from. We must terminate
+       the thread first. Keep track of thread handle, and close it when
+       thread is dying. Start reader thread with the lower-level
+       CreateThread() instead of _beginthreadex() from the C runtime, in
+       order to be able to use TerminateThread(). Hopefuly this isn't
+       harmful.
+
+       * glib.def: Update.
+
+       * tests/makefile.{mingw,msc}.in (TESTS): Add mainloop-test and
+       unicode-encoding.
+
+       * tests/mainloop-test.c: Portability: <unistd.h>, need <fcntl.h>
+       on Win32.
+
+       * tests/unicode-encoding.c (process): Add missing "line" argument
+       to fail(). On Win32, convert UTF-16LE, as libiconv'c ivonf always
+       converts to UTF-16BE if we ask for unspecific UTF-16.
+       (main) Handle also '\r'.
+
 Fri Jan  5 11:25:42 2001  Owen Taylor  <otaylor@redhat.com>
 
        * configure.in (PACKAGE): move $enable_debug down below
index 6478f6a..0e60410 100644 (file)
@@ -1,3 +1,30 @@
+2001-01-06  Tor Lillqvist  <tml@iki.fi>
+
+       * gconvert.c (g_locale_to_utf8, g_locale_from_utf8): Get len using
+       strlen() if arg is negative in the Win32 code, too.
+
+       * giowin32.c: Changes necessary to be able to run
+       mainloop-test. We can't close the fd that our (internal) reader
+       thread is sitting doing a blocking read() from. We must terminate
+       the thread first. Keep track of thread handle, and close it when
+       thread is dying. Start reader thread with the lower-level
+       CreateThread() instead of _beginthreadex() from the C runtime, in
+       order to be able to use TerminateThread(). Hopefuly this isn't
+       harmful.
+
+       * glib.def: Update.
+
+       * tests/makefile.{mingw,msc}.in (TESTS): Add mainloop-test and
+       unicode-encoding.
+
+       * tests/mainloop-test.c: Portability: <unistd.h>, need <fcntl.h>
+       on Win32.
+
+       * tests/unicode-encoding.c (process): Add missing "line" argument
+       to fail(). On Win32, convert UTF-16LE, as libiconv'c ivonf always
+       converts to UTF-16BE if we ask for unspecific UTF-16.
+       (main) Handle also '\r'.
+
 Fri Jan  5 11:25:42 2001  Owen Taylor  <otaylor@redhat.com>
 
        * configure.in (PACKAGE): move $enable_debug down below
index 6478f6a..0e60410 100644 (file)
@@ -1,3 +1,30 @@
+2001-01-06  Tor Lillqvist  <tml@iki.fi>
+
+       * gconvert.c (g_locale_to_utf8, g_locale_from_utf8): Get len using
+       strlen() if arg is negative in the Win32 code, too.
+
+       * giowin32.c: Changes necessary to be able to run
+       mainloop-test. We can't close the fd that our (internal) reader
+       thread is sitting doing a blocking read() from. We must terminate
+       the thread first. Keep track of thread handle, and close it when
+       thread is dying. Start reader thread with the lower-level
+       CreateThread() instead of _beginthreadex() from the C runtime, in
+       order to be able to use TerminateThread(). Hopefuly this isn't
+       harmful.
+
+       * glib.def: Update.
+
+       * tests/makefile.{mingw,msc}.in (TESTS): Add mainloop-test and
+       unicode-encoding.
+
+       * tests/mainloop-test.c: Portability: <unistd.h>, need <fcntl.h>
+       on Win32.
+
+       * tests/unicode-encoding.c (process): Add missing "line" argument
+       to fail(). On Win32, convert UTF-16LE, as libiconv'c ivonf always
+       converts to UTF-16BE if we ask for unspecific UTF-16.
+       (main) Handle also '\r'.
+
 Fri Jan  5 11:25:42 2001  Owen Taylor  <otaylor@redhat.com>
 
        * configure.in (PACKAGE): move $enable_debug down below
index 6478f6a..0e60410 100644 (file)
@@ -1,3 +1,30 @@
+2001-01-06  Tor Lillqvist  <tml@iki.fi>
+
+       * gconvert.c (g_locale_to_utf8, g_locale_from_utf8): Get len using
+       strlen() if arg is negative in the Win32 code, too.
+
+       * giowin32.c: Changes necessary to be able to run
+       mainloop-test. We can't close the fd that our (internal) reader
+       thread is sitting doing a blocking read() from. We must terminate
+       the thread first. Keep track of thread handle, and close it when
+       thread is dying. Start reader thread with the lower-level
+       CreateThread() instead of _beginthreadex() from the C runtime, in
+       order to be able to use TerminateThread(). Hopefuly this isn't
+       harmful.
+
+       * glib.def: Update.
+
+       * tests/makefile.{mingw,msc}.in (TESTS): Add mainloop-test and
+       unicode-encoding.
+
+       * tests/mainloop-test.c: Portability: <unistd.h>, need <fcntl.h>
+       on Win32.
+
+       * tests/unicode-encoding.c (process): Add missing "line" argument
+       to fail(). On Win32, convert UTF-16LE, as libiconv'c ivonf always
+       converts to UTF-16BE if we ask for unspecific UTF-16.
+       (main) Handle also '\r'.
+
 Fri Jan  5 11:25:42 2001  Owen Taylor  <otaylor@redhat.com>
 
        * configure.in (PACKAGE): move $enable_debug down below
index 6478f6a..0e60410 100644 (file)
@@ -1,3 +1,30 @@
+2001-01-06  Tor Lillqvist  <tml@iki.fi>
+
+       * gconvert.c (g_locale_to_utf8, g_locale_from_utf8): Get len using
+       strlen() if arg is negative in the Win32 code, too.
+
+       * giowin32.c: Changes necessary to be able to run
+       mainloop-test. We can't close the fd that our (internal) reader
+       thread is sitting doing a blocking read() from. We must terminate
+       the thread first. Keep track of thread handle, and close it when
+       thread is dying. Start reader thread with the lower-level
+       CreateThread() instead of _beginthreadex() from the C runtime, in
+       order to be able to use TerminateThread(). Hopefuly this isn't
+       harmful.
+
+       * glib.def: Update.
+
+       * tests/makefile.{mingw,msc}.in (TESTS): Add mainloop-test and
+       unicode-encoding.
+
+       * tests/mainloop-test.c: Portability: <unistd.h>, need <fcntl.h>
+       on Win32.
+
+       * tests/unicode-encoding.c (process): Add missing "line" argument
+       to fail(). On Win32, convert UTF-16LE, as libiconv'c ivonf always
+       converts to UTF-16BE if we ask for unspecific UTF-16.
+       (main) Handle also '\r'.
+
 Fri Jan  5 11:25:42 2001  Owen Taylor  <otaylor@redhat.com>
 
        * configure.in (PACKAGE): move $enable_debug down below
index 344902f..49cfad9 100644 (file)
@@ -519,11 +519,13 @@ g_locale_to_utf8 (const gchar  *opsysstring,
 #ifdef G_OS_WIN32
 
   gint i, clen, total_len, wclen, first;
-  const gint len = len < 0 ? strlen (opsysstring) : len;
   wchar_t *wcs, wc;
   gchar *result, *bp;
   const wchar_t *wcp;
 
+  if (len == -1)
+    len = strlen (opsysstring);
+  
   wcs = g_new (wchar_t, len);
   wclen = MultiByteToWideChar (CP_ACP, 0, opsysstring, len, wcs, len);
 
@@ -658,12 +660,14 @@ g_locale_from_utf8 (const gchar *utf8string,
 #ifdef G_OS_WIN32
 
   gint i, mask, clen, mblen;
-  const gint len = len < 0 ? strlen (utf8string) : len;
   wchar_t *wcs, *wcp;
   gchar *result;
   guchar *cp, *end, c;
   gint n;
   
+  if (len == -1)
+    len = strlen (utf8string);
+  
   /* First convert to wide chars */
   cp = (guchar *) utf8string;
   end = cp + len;
index beee622..c6f2b79 100644 (file)
@@ -90,6 +90,7 @@ struct _GIOWin32Channel {
                                 */
   guint thread_id;             /* If non-NULL has a reader thread, or has
                                 * had.*/
+  HANDLE thread_handle;
   HANDLE data_avail_event;
   HANDLE space_avail_event;
   CRITICAL_SECTION mutex;
@@ -125,6 +126,7 @@ g_io_channel_win32_init (GIOWin32Channel *channel)
   channel->thread_id = 0;
   channel->data_avail_event = NULL;
   channel->space_avail_event = NULL;
+  InitializeCriticalSection (&channel->mutex);
 }
 
 static void
@@ -145,7 +147,6 @@ create_events (GIOWin32Channel *channel)
       gchar *msg = g_win32_error_message (GetLastError ());
       g_error ("Error creating event: %s", msg);
     }
-  InitializeCriticalSection (&channel->mutex);
 }
 
 static unsigned __stdcall
@@ -210,13 +211,15 @@ reader_thread (void *parameter)
 
       nbytes = (*channel->reader) (channel->fd, buffer, nbytes);
       
-      if (nbytes <= 0)
-       break;
-
       LOCK (channel->mutex);
+
       if (channel->debug)
        g_print ("thread %#x: got %d bytes, rdp=%d, wrp=%d\n",
                 channel->thread_id, nbytes, channel->rdp, channel->wrp);
+
+      if (nbytes <= 0)
+       break;
+
       channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
       if (channel->debug)
        g_print ("thread %#x: rdp=%d, wrp=%d, setting data available\n",
@@ -225,7 +228,6 @@ reader_thread (void *parameter)
       UNLOCK (channel->mutex);
     }
   
-  LOCK (channel->mutex);
   channel->running = FALSE;
   if (channel->debug)
     g_print ("thread %#x: got EOF, rdp=%d, wrp=%d, setting data available\n",
@@ -235,11 +237,15 @@ reader_thread (void *parameter)
   
   g_io_channel_unref((GIOChannel *) channel);
   
+#if 0
   /* All of the Microsoft docs say we should explicitly
    * end the thread...
    */
   _endthreadex(1);
-  
+#endif
+
+  CloseHandle (channel->thread_handle);
+
   return 0;
 }
 
@@ -249,9 +255,21 @@ create_reader_thread (GIOWin32Channel *channel,
 {
   channel->reader = reader;
 
-  if (_beginthreadex (NULL, 0, reader_thread, channel, 0,
-                     &channel->thread_id) == 0)
+#if 0
+  if ((channel->thread_handle =
+       _beginthreadex (NULL, 0, reader_thread, channel, 0,
+                      &channel->thread_id)) == 0)
     g_warning ("Error creating reader thread: %s", strerror (errno));
+#else
+  if ((channel->thread_handle =
+       CreateThread (NULL, 0, reader_thread, channel, 0,
+                    &channel->thread_id)) == 0)
+    {
+      gchar *msg = g_win32_error_message (GetLastError ());
+      g_warning ("Error creating reader thread: %s", msg);
+      g_free (msg);
+    }
+#endif
   WaitForSingleObject (channel->space_avail_event, INFINITE);
 }
 
@@ -275,6 +293,8 @@ buffer_read (GIOWin32Channel *channel,
       if (channel->debug)
        g_print ("waiting for data from thread %#x\n", channel->thread_id);
       WaitForSingleObject (channel->data_avail_event, INFINITE);
+      if (channel->debug)
+       g_print ("done waiting for data from thread %#x\n", channel->thread_id);
       LOCK (channel->mutex);
       if (channel->rdp == channel->wrp && !channel->running)
        {
@@ -479,6 +499,11 @@ g_io_win32_free (GIOChannel *channel)
 {
   GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
   
+  if (win32_channel->debug)
+    g_print ("thread %#x: freeing channel, fd: %d\n",
+            win32_channel->thread_id,
+            win32_channel->fd);
+
   if (win32_channel->buffer)
     {
       CloseHandle (win32_channel->data_avail_event);
@@ -639,8 +664,33 @@ g_io_win32_fd_close (GIOChannel *channel)
 {
   GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
   
+  if (win32_channel->debug)
+    g_print ("thread %#x: closing fd %d\n",
+            win32_channel->thread_id,
+            win32_channel->fd);
+  LOCK (win32_channel->mutex);
+  if (win32_channel->running)
+    {
+      if (win32_channel->debug)
+       g_print ("thread %#x: running, terminating it\n",
+                win32_channel->thread_id);
+      TerminateThread (win32_channel->thread_handle, 0);
+      if (win32_channel->debug)
+       g_print ("thread %#x: terminated, setting id to 0, closing handle\n",
+                win32_channel->thread_id);
+      win32_channel->thread_id = 0;
+      CloseHandle (win32_channel->thread_handle);
+      win32_channel->running = FALSE;
+      SetEvent (win32_channel->data_avail_event);
+    }
+  UNLOCK (win32_channel->mutex);
+  if (win32_channel->debug)
+    g_print ("closing fd %d\n", win32_channel->fd);
   close (win32_channel->fd);
-  return;
+  if (win32_channel->debug)
+    g_print ("closed fd %d, setting to -1\n",
+            win32_channel->fd);
+  win32_channel->fd = -1;
 }
 
 static int
@@ -734,7 +784,12 @@ g_io_win32_sock_close (GIOChannel *channel)
 {
   GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
 
+  if (win32_channel->debug)
+    g_print ("thread %#x: closing socket %d\n",
+            win32_channel->thread_id,
+            win32_channel->fd);
   closesocket (win32_channel->fd);
+  win32_channel->fd = -1;
 }
 
 static int
index 45f1473..994d083 100644 (file)
--- a/glib.def
+++ b/glib.def
@@ -182,6 +182,7 @@ EXPORTS
        g_io_channel_win32_poll
        g_io_channel_win32_set_debug
        g_io_channel_write
+       g_io_create_watch
        g_list_alloc
        g_list_append
        g_list_concat
@@ -534,6 +535,7 @@ EXPORTS
        g_tree_traverse
        g_tuples_destroy
        g_tuples_index
+       g_ucs4_to_utf16
        g_ucs4_to_utf8
        g_unichar_break_type
        g_unichar_digit_value
@@ -560,6 +562,8 @@ EXPORTS
        g_unicode_canonical_decomposition
        g_unicode_canonical_ordering
        g_usleep
+       g_utf16_to_ucs4
+       g_utf16_to_utf8
        g_utf8_find_next_char
        g_utf8_find_prev_char
        g_utf8_get_char
@@ -571,6 +575,8 @@ EXPORTS
        g_utf8_strlen
        g_utf8_strncpy
        g_utf8_to_ucs4
+       g_utf8_to_ucs4_fast
+       g_utf8_to_utf16
        g_utf8_validate
        g_vsnprintf
        g_win32_closedir
index 344902f..49cfad9 100644 (file)
@@ -519,11 +519,13 @@ g_locale_to_utf8 (const gchar  *opsysstring,
 #ifdef G_OS_WIN32
 
   gint i, clen, total_len, wclen, first;
-  const gint len = len < 0 ? strlen (opsysstring) : len;
   wchar_t *wcs, wc;
   gchar *result, *bp;
   const wchar_t *wcp;
 
+  if (len == -1)
+    len = strlen (opsysstring);
+  
   wcs = g_new (wchar_t, len);
   wclen = MultiByteToWideChar (CP_ACP, 0, opsysstring, len, wcs, len);
 
@@ -658,12 +660,14 @@ g_locale_from_utf8 (const gchar *utf8string,
 #ifdef G_OS_WIN32
 
   gint i, mask, clen, mblen;
-  const gint len = len < 0 ? strlen (utf8string) : len;
   wchar_t *wcs, *wcp;
   gchar *result;
   guchar *cp, *end, c;
   gint n;
   
+  if (len == -1)
+    len = strlen (utf8string);
+  
   /* First convert to wide chars */
   cp = (guchar *) utf8string;
   end = cp + len;
index beee622..c6f2b79 100644 (file)
@@ -90,6 +90,7 @@ struct _GIOWin32Channel {
                                 */
   guint thread_id;             /* If non-NULL has a reader thread, or has
                                 * had.*/
+  HANDLE thread_handle;
   HANDLE data_avail_event;
   HANDLE space_avail_event;
   CRITICAL_SECTION mutex;
@@ -125,6 +126,7 @@ g_io_channel_win32_init (GIOWin32Channel *channel)
   channel->thread_id = 0;
   channel->data_avail_event = NULL;
   channel->space_avail_event = NULL;
+  InitializeCriticalSection (&channel->mutex);
 }
 
 static void
@@ -145,7 +147,6 @@ create_events (GIOWin32Channel *channel)
       gchar *msg = g_win32_error_message (GetLastError ());
       g_error ("Error creating event: %s", msg);
     }
-  InitializeCriticalSection (&channel->mutex);
 }
 
 static unsigned __stdcall
@@ -210,13 +211,15 @@ reader_thread (void *parameter)
 
       nbytes = (*channel->reader) (channel->fd, buffer, nbytes);
       
-      if (nbytes <= 0)
-       break;
-
       LOCK (channel->mutex);
+
       if (channel->debug)
        g_print ("thread %#x: got %d bytes, rdp=%d, wrp=%d\n",
                 channel->thread_id, nbytes, channel->rdp, channel->wrp);
+
+      if (nbytes <= 0)
+       break;
+
       channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
       if (channel->debug)
        g_print ("thread %#x: rdp=%d, wrp=%d, setting data available\n",
@@ -225,7 +228,6 @@ reader_thread (void *parameter)
       UNLOCK (channel->mutex);
     }
   
-  LOCK (channel->mutex);
   channel->running = FALSE;
   if (channel->debug)
     g_print ("thread %#x: got EOF, rdp=%d, wrp=%d, setting data available\n",
@@ -235,11 +237,15 @@ reader_thread (void *parameter)
   
   g_io_channel_unref((GIOChannel *) channel);
   
+#if 0
   /* All of the Microsoft docs say we should explicitly
    * end the thread...
    */
   _endthreadex(1);
-  
+#endif
+
+  CloseHandle (channel->thread_handle);
+
   return 0;
 }
 
@@ -249,9 +255,21 @@ create_reader_thread (GIOWin32Channel *channel,
 {
   channel->reader = reader;
 
-  if (_beginthreadex (NULL, 0, reader_thread, channel, 0,
-                     &channel->thread_id) == 0)
+#if 0
+  if ((channel->thread_handle =
+       _beginthreadex (NULL, 0, reader_thread, channel, 0,
+                      &channel->thread_id)) == 0)
     g_warning ("Error creating reader thread: %s", strerror (errno));
+#else
+  if ((channel->thread_handle =
+       CreateThread (NULL, 0, reader_thread, channel, 0,
+                    &channel->thread_id)) == 0)
+    {
+      gchar *msg = g_win32_error_message (GetLastError ());
+      g_warning ("Error creating reader thread: %s", msg);
+      g_free (msg);
+    }
+#endif
   WaitForSingleObject (channel->space_avail_event, INFINITE);
 }
 
@@ -275,6 +293,8 @@ buffer_read (GIOWin32Channel *channel,
       if (channel->debug)
        g_print ("waiting for data from thread %#x\n", channel->thread_id);
       WaitForSingleObject (channel->data_avail_event, INFINITE);
+      if (channel->debug)
+       g_print ("done waiting for data from thread %#x\n", channel->thread_id);
       LOCK (channel->mutex);
       if (channel->rdp == channel->wrp && !channel->running)
        {
@@ -479,6 +499,11 @@ g_io_win32_free (GIOChannel *channel)
 {
   GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
   
+  if (win32_channel->debug)
+    g_print ("thread %#x: freeing channel, fd: %d\n",
+            win32_channel->thread_id,
+            win32_channel->fd);
+
   if (win32_channel->buffer)
     {
       CloseHandle (win32_channel->data_avail_event);
@@ -639,8 +664,33 @@ g_io_win32_fd_close (GIOChannel *channel)
 {
   GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
   
+  if (win32_channel->debug)
+    g_print ("thread %#x: closing fd %d\n",
+            win32_channel->thread_id,
+            win32_channel->fd);
+  LOCK (win32_channel->mutex);
+  if (win32_channel->running)
+    {
+      if (win32_channel->debug)
+       g_print ("thread %#x: running, terminating it\n",
+                win32_channel->thread_id);
+      TerminateThread (win32_channel->thread_handle, 0);
+      if (win32_channel->debug)
+       g_print ("thread %#x: terminated, setting id to 0, closing handle\n",
+                win32_channel->thread_id);
+      win32_channel->thread_id = 0;
+      CloseHandle (win32_channel->thread_handle);
+      win32_channel->running = FALSE;
+      SetEvent (win32_channel->data_avail_event);
+    }
+  UNLOCK (win32_channel->mutex);
+  if (win32_channel->debug)
+    g_print ("closing fd %d\n", win32_channel->fd);
   close (win32_channel->fd);
-  return;
+  if (win32_channel->debug)
+    g_print ("closed fd %d, setting to -1\n",
+            win32_channel->fd);
+  win32_channel->fd = -1;
 }
 
 static int
@@ -734,7 +784,12 @@ g_io_win32_sock_close (GIOChannel *channel)
 {
   GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
 
+  if (win32_channel->debug)
+    g_print ("thread %#x: closing socket %d\n",
+            win32_channel->thread_id,
+            win32_channel->fd);
   closesocket (win32_channel->fd);
+  win32_channel->fd = -1;
 }
 
 static int
index 45f1473..994d083 100644 (file)
@@ -182,6 +182,7 @@ EXPORTS
        g_io_channel_win32_poll
        g_io_channel_win32_set_debug
        g_io_channel_write
+       g_io_create_watch
        g_list_alloc
        g_list_append
        g_list_concat
@@ -534,6 +535,7 @@ EXPORTS
        g_tree_traverse
        g_tuples_destroy
        g_tuples_index
+       g_ucs4_to_utf16
        g_ucs4_to_utf8
        g_unichar_break_type
        g_unichar_digit_value
@@ -560,6 +562,8 @@ EXPORTS
        g_unicode_canonical_decomposition
        g_unicode_canonical_ordering
        g_usleep
+       g_utf16_to_ucs4
+       g_utf16_to_utf8
        g_utf8_find_next_char
        g_utf8_find_prev_char
        g_utf8_get_char
@@ -571,6 +575,8 @@ EXPORTS
        g_utf8_strlen
        g_utf8_strncpy
        g_utf8_to_ucs4
+       g_utf8_to_ucs4_fast
+       g_utf8_to_utf16
        g_utf8_validate
        g_vsnprintf
        g_win32_closedir
index 422a669..8710b3f 100644 (file)
@@ -1,9 +1,15 @@
 #include <errno.h>
 #include <glib.h>
+#ifdef G_OS_UNIX
 #include <unistd.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 
+#ifdef G_OS_WIN32
+#include <fcntl.h>             /* For _O_BINARY used by pipe() macro */
+#endif
+
 #define ITERS 10000
 #define INCREMENT 10
 #define NTHREADS 4
index c6b48d8..3a1ddf4 100644 (file)
@@ -22,6 +22,7 @@ TESTS = \
        gio-test.exe    \
        hash-test.exe   \
        list-test.exe   \
+       mainloop-test.exe\
        markup-test.exe \
        node-test.exe   \
        queue-test.exe  \
@@ -35,7 +36,8 @@ TESTS = \
        thread-test.exe \
        threadpool-test.exe\
        tree-test.exe   \
-       type-test.exe
+       type-test.exe   \
+       unicode-encoding.exe
 
 all:   $(TESTS)
 
index 8ecda35..cfbcb72 100644 (file)
@@ -22,6 +22,7 @@ TESTS = \
        gio-test.exe    \
        hash-test.exe   \
        list-test.exe   \
+       mainloop-test.exe\
        markup-test.exe \
        node-test.exe   \
        queue-test.exe  \
@@ -36,7 +37,8 @@ TESTS = \
        thread-test.exe \
        threadpool-test.exe\
        tree-test.exe   \
-       type-test.exe
+       type-test.exe   \
+       unicode-encoding.exe
 
 all :  $(TESTS)
 
index 498137b..9065b9e 100644 (file)
@@ -192,7 +192,13 @@ process (gint      line,
       gint n_chars;
       gchar *utf8_result;
 
-      if (!(utf16_expected_tmp = (gunichar2 *)g_convert (utf8, -1, "UTF-16", "UTF-8",
+#ifdef G_OS_WIN32
+#define TARGET "UTF-16LE"
+#else
+#define TARGET "UTF-16"
+#endif
+
+      if (!(utf16_expected_tmp = (gunichar2 *)g_convert (utf8, -1, TARGET, "UTF-8",
                                                         NULL, &bytes_written, NULL)))
        {
          fail ("line %d: could not convert to UTF-16 via g_convert\n", line);
@@ -210,7 +216,7 @@ process (gint      line,
        }
       else if (utf16_expected_tmp[0] == 0xfffe) /* ANTI-BOM */
        {
-         fail ("line %d: conversion via iconv to \"UTF-16\" is not native-endian\n");
+         fail ("line %d: conversion via iconv to \"UTF-16\" is not native-endian\n", line);
          return;
        }
       else
@@ -315,7 +321,7 @@ main (int argc, char **argv)
   if (!srcdir)
     srcdir = ".";
   
-  testfile = g_strconcat (srcdir, "/", "utf8.txt", NULL);
+  testfile = g_strconcat (srcdir, G_DIR_SEPARATOR_S "utf8.txt", NULL);
   
   g_file_get_contents (testfile, &contents, NULL, &error);
   if (error)
@@ -332,10 +338,10 @@ main (int argc, char **argv)
        p++;
 
       end = p;
-      while (*end && *end != '\n')
+      while (*end && (*end != '\r' && *end != '\n'))
        end++;
       
-      if (!*p || *p == '#' || *p == '\n')
+      if (!*p || *p == '#' || *p == '\r' || *p == '\n')
        goto next_line;
 
       tmp = g_strstrip (g_strndup (p, end - p));
@@ -401,6 +407,8 @@ main (int argc, char **argv)
       
     next_line:
       p = end;
+      if (*p && *p == '\r')
+       p++;
       if (*p && *p == '\n')
        p++;