Get len using strlen() if arg is negative in the Win32 code, too.

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'.
This commit is contained in:
Tor Lillqvist 2001-01-06 03:09:46 +00:00 committed by Tor Lillqvist
parent 956f00ed96
commit deb68e1592
18 changed files with 393 additions and 29 deletions

View 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> Fri Jan 5 11:25:42 2001 Owen Taylor <otaylor@redhat.com>
* configure.in (PACKAGE): move $enable_debug down below * configure.in (PACKAGE): move $enable_debug down below

View 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> Fri Jan 5 11:25:42 2001 Owen Taylor <otaylor@redhat.com>
* configure.in (PACKAGE): move $enable_debug down below * configure.in (PACKAGE): move $enable_debug down below

View 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> Fri Jan 5 11:25:42 2001 Owen Taylor <otaylor@redhat.com>
* configure.in (PACKAGE): move $enable_debug down below * configure.in (PACKAGE): move $enable_debug down below

View 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> Fri Jan 5 11:25:42 2001 Owen Taylor <otaylor@redhat.com>
* configure.in (PACKAGE): move $enable_debug down below * configure.in (PACKAGE): move $enable_debug down below

View 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> Fri Jan 5 11:25:42 2001 Owen Taylor <otaylor@redhat.com>
* configure.in (PACKAGE): move $enable_debug down below * configure.in (PACKAGE): move $enable_debug down below

View 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> Fri Jan 5 11:25:42 2001 Owen Taylor <otaylor@redhat.com>
* configure.in (PACKAGE): move $enable_debug down below * configure.in (PACKAGE): move $enable_debug down below

View 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> Fri Jan 5 11:25:42 2001 Owen Taylor <otaylor@redhat.com>
* configure.in (PACKAGE): move $enable_debug down below * configure.in (PACKAGE): move $enable_debug down below

View 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> Fri Jan 5 11:25:42 2001 Owen Taylor <otaylor@redhat.com>
* configure.in (PACKAGE): move $enable_debug down below * configure.in (PACKAGE): move $enable_debug down below

View File

@ -519,11 +519,13 @@ g_locale_to_utf8 (const gchar *opsysstring,
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
gint i, clen, total_len, wclen, first; gint i, clen, total_len, wclen, first;
const gint len = len < 0 ? strlen (opsysstring) : len;
wchar_t *wcs, wc; wchar_t *wcs, wc;
gchar *result, *bp; gchar *result, *bp;
const wchar_t *wcp; const wchar_t *wcp;
if (len == -1)
len = strlen (opsysstring);
wcs = g_new (wchar_t, len); wcs = g_new (wchar_t, len);
wclen = MultiByteToWideChar (CP_ACP, 0, opsysstring, len, wcs, 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 #ifdef G_OS_WIN32
gint i, mask, clen, mblen; gint i, mask, clen, mblen;
const gint len = len < 0 ? strlen (utf8string) : len;
wchar_t *wcs, *wcp; wchar_t *wcs, *wcp;
gchar *result; gchar *result;
guchar *cp, *end, c; guchar *cp, *end, c;
gint n; gint n;
if (len == -1)
len = strlen (utf8string);
/* First convert to wide chars */ /* First convert to wide chars */
cp = (guchar *) utf8string; cp = (guchar *) utf8string;
end = cp + len; end = cp + len;

View File

@ -90,6 +90,7 @@ struct _GIOWin32Channel {
*/ */
guint thread_id; /* If non-NULL has a reader thread, or has guint thread_id; /* If non-NULL has a reader thread, or has
* had.*/ * had.*/
HANDLE thread_handle;
HANDLE data_avail_event; HANDLE data_avail_event;
HANDLE space_avail_event; HANDLE space_avail_event;
CRITICAL_SECTION mutex; CRITICAL_SECTION mutex;
@ -125,6 +126,7 @@ g_io_channel_win32_init (GIOWin32Channel *channel)
channel->thread_id = 0; channel->thread_id = 0;
channel->data_avail_event = NULL; channel->data_avail_event = NULL;
channel->space_avail_event = NULL; channel->space_avail_event = NULL;
InitializeCriticalSection (&channel->mutex);
} }
static void static void
@ -145,7 +147,6 @@ create_events (GIOWin32Channel *channel)
gchar *msg = g_win32_error_message (GetLastError ()); gchar *msg = g_win32_error_message (GetLastError ());
g_error ("Error creating event: %s", msg); g_error ("Error creating event: %s", msg);
} }
InitializeCriticalSection (&channel->mutex);
} }
static unsigned __stdcall static unsigned __stdcall
@ -210,13 +211,15 @@ reader_thread (void *parameter)
nbytes = (*channel->reader) (channel->fd, buffer, nbytes); nbytes = (*channel->reader) (channel->fd, buffer, nbytes);
if (nbytes <= 0)
break;
LOCK (channel->mutex); LOCK (channel->mutex);
if (channel->debug) if (channel->debug)
g_print ("thread %#x: got %d bytes, rdp=%d, wrp=%d\n", g_print ("thread %#x: got %d bytes, rdp=%d, wrp=%d\n",
channel->thread_id, nbytes, channel->rdp, channel->wrp); channel->thread_id, nbytes, channel->rdp, channel->wrp);
if (nbytes <= 0)
break;
channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE; channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
if (channel->debug) if (channel->debug)
g_print ("thread %#x: rdp=%d, wrp=%d, setting data available\n", g_print ("thread %#x: rdp=%d, wrp=%d, setting data available\n",
@ -225,7 +228,6 @@ reader_thread (void *parameter)
UNLOCK (channel->mutex); UNLOCK (channel->mutex);
} }
LOCK (channel->mutex);
channel->running = FALSE; channel->running = FALSE;
if (channel->debug) if (channel->debug)
g_print ("thread %#x: got EOF, rdp=%d, wrp=%d, setting data available\n", 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); g_io_channel_unref((GIOChannel *) channel);
#if 0
/* All of the Microsoft docs say we should explicitly /* All of the Microsoft docs say we should explicitly
* end the thread... * end the thread...
*/ */
_endthreadex(1); _endthreadex(1);
#endif
CloseHandle (channel->thread_handle);
return 0; return 0;
} }
@ -249,9 +255,21 @@ create_reader_thread (GIOWin32Channel *channel,
{ {
channel->reader = reader; channel->reader = reader;
if (_beginthreadex (NULL, 0, reader_thread, channel, 0, #if 0
&channel->thread_id) == 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)); 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); WaitForSingleObject (channel->space_avail_event, INFINITE);
} }
@ -275,6 +293,8 @@ buffer_read (GIOWin32Channel *channel,
if (channel->debug) if (channel->debug)
g_print ("waiting for data from thread %#x\n", channel->thread_id); g_print ("waiting for data from thread %#x\n", channel->thread_id);
WaitForSingleObject (channel->data_avail_event, INFINITE); 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); LOCK (channel->mutex);
if (channel->rdp == channel->wrp && !channel->running) if (channel->rdp == channel->wrp && !channel->running)
{ {
@ -479,6 +499,11 @@ g_io_win32_free (GIOChannel *channel)
{ {
GIOWin32Channel *win32_channel = (GIOWin32Channel *) 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) if (win32_channel->buffer)
{ {
CloseHandle (win32_channel->data_avail_event); CloseHandle (win32_channel->data_avail_event);
@ -639,8 +664,33 @@ g_io_win32_fd_close (GIOChannel *channel)
{ {
GIOWin32Channel *win32_channel = (GIOWin32Channel *) 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); 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 static int
@ -734,7 +784,12 @@ g_io_win32_sock_close (GIOChannel *channel)
{ {
GIOWin32Channel *win32_channel = (GIOWin32Channel *) 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); closesocket (win32_channel->fd);
win32_channel->fd = -1;
} }
static int static int

View File

@ -182,6 +182,7 @@ EXPORTS
g_io_channel_win32_poll g_io_channel_win32_poll
g_io_channel_win32_set_debug g_io_channel_win32_set_debug
g_io_channel_write g_io_channel_write
g_io_create_watch
g_list_alloc g_list_alloc
g_list_append g_list_append
g_list_concat g_list_concat
@ -534,6 +535,7 @@ EXPORTS
g_tree_traverse g_tree_traverse
g_tuples_destroy g_tuples_destroy
g_tuples_index g_tuples_index
g_ucs4_to_utf16
g_ucs4_to_utf8 g_ucs4_to_utf8
g_unichar_break_type g_unichar_break_type
g_unichar_digit_value g_unichar_digit_value
@ -560,6 +562,8 @@ EXPORTS
g_unicode_canonical_decomposition g_unicode_canonical_decomposition
g_unicode_canonical_ordering g_unicode_canonical_ordering
g_usleep g_usleep
g_utf16_to_ucs4
g_utf16_to_utf8
g_utf8_find_next_char g_utf8_find_next_char
g_utf8_find_prev_char g_utf8_find_prev_char
g_utf8_get_char g_utf8_get_char
@ -571,6 +575,8 @@ EXPORTS
g_utf8_strlen g_utf8_strlen
g_utf8_strncpy g_utf8_strncpy
g_utf8_to_ucs4 g_utf8_to_ucs4
g_utf8_to_ucs4_fast
g_utf8_to_utf16
g_utf8_validate g_utf8_validate
g_vsnprintf g_vsnprintf
g_win32_closedir g_win32_closedir

View File

@ -519,11 +519,13 @@ g_locale_to_utf8 (const gchar *opsysstring,
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
gint i, clen, total_len, wclen, first; gint i, clen, total_len, wclen, first;
const gint len = len < 0 ? strlen (opsysstring) : len;
wchar_t *wcs, wc; wchar_t *wcs, wc;
gchar *result, *bp; gchar *result, *bp;
const wchar_t *wcp; const wchar_t *wcp;
if (len == -1)
len = strlen (opsysstring);
wcs = g_new (wchar_t, len); wcs = g_new (wchar_t, len);
wclen = MultiByteToWideChar (CP_ACP, 0, opsysstring, len, wcs, 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 #ifdef G_OS_WIN32
gint i, mask, clen, mblen; gint i, mask, clen, mblen;
const gint len = len < 0 ? strlen (utf8string) : len;
wchar_t *wcs, *wcp; wchar_t *wcs, *wcp;
gchar *result; gchar *result;
guchar *cp, *end, c; guchar *cp, *end, c;
gint n; gint n;
if (len == -1)
len = strlen (utf8string);
/* First convert to wide chars */ /* First convert to wide chars */
cp = (guchar *) utf8string; cp = (guchar *) utf8string;
end = cp + len; end = cp + len;

View File

@ -90,6 +90,7 @@ struct _GIOWin32Channel {
*/ */
guint thread_id; /* If non-NULL has a reader thread, or has guint thread_id; /* If non-NULL has a reader thread, or has
* had.*/ * had.*/
HANDLE thread_handle;
HANDLE data_avail_event; HANDLE data_avail_event;
HANDLE space_avail_event; HANDLE space_avail_event;
CRITICAL_SECTION mutex; CRITICAL_SECTION mutex;
@ -125,6 +126,7 @@ g_io_channel_win32_init (GIOWin32Channel *channel)
channel->thread_id = 0; channel->thread_id = 0;
channel->data_avail_event = NULL; channel->data_avail_event = NULL;
channel->space_avail_event = NULL; channel->space_avail_event = NULL;
InitializeCriticalSection (&channel->mutex);
} }
static void static void
@ -145,7 +147,6 @@ create_events (GIOWin32Channel *channel)
gchar *msg = g_win32_error_message (GetLastError ()); gchar *msg = g_win32_error_message (GetLastError ());
g_error ("Error creating event: %s", msg); g_error ("Error creating event: %s", msg);
} }
InitializeCriticalSection (&channel->mutex);
} }
static unsigned __stdcall static unsigned __stdcall
@ -210,13 +211,15 @@ reader_thread (void *parameter)
nbytes = (*channel->reader) (channel->fd, buffer, nbytes); nbytes = (*channel->reader) (channel->fd, buffer, nbytes);
if (nbytes <= 0)
break;
LOCK (channel->mutex); LOCK (channel->mutex);
if (channel->debug) if (channel->debug)
g_print ("thread %#x: got %d bytes, rdp=%d, wrp=%d\n", g_print ("thread %#x: got %d bytes, rdp=%d, wrp=%d\n",
channel->thread_id, nbytes, channel->rdp, channel->wrp); channel->thread_id, nbytes, channel->rdp, channel->wrp);
if (nbytes <= 0)
break;
channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE; channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
if (channel->debug) if (channel->debug)
g_print ("thread %#x: rdp=%d, wrp=%d, setting data available\n", g_print ("thread %#x: rdp=%d, wrp=%d, setting data available\n",
@ -225,7 +228,6 @@ reader_thread (void *parameter)
UNLOCK (channel->mutex); UNLOCK (channel->mutex);
} }
LOCK (channel->mutex);
channel->running = FALSE; channel->running = FALSE;
if (channel->debug) if (channel->debug)
g_print ("thread %#x: got EOF, rdp=%d, wrp=%d, setting data available\n", 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); g_io_channel_unref((GIOChannel *) channel);
#if 0
/* All of the Microsoft docs say we should explicitly /* All of the Microsoft docs say we should explicitly
* end the thread... * end the thread...
*/ */
_endthreadex(1); _endthreadex(1);
#endif
CloseHandle (channel->thread_handle);
return 0; return 0;
} }
@ -249,9 +255,21 @@ create_reader_thread (GIOWin32Channel *channel,
{ {
channel->reader = reader; channel->reader = reader;
if (_beginthreadex (NULL, 0, reader_thread, channel, 0, #if 0
&channel->thread_id) == 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)); 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); WaitForSingleObject (channel->space_avail_event, INFINITE);
} }
@ -275,6 +293,8 @@ buffer_read (GIOWin32Channel *channel,
if (channel->debug) if (channel->debug)
g_print ("waiting for data from thread %#x\n", channel->thread_id); g_print ("waiting for data from thread %#x\n", channel->thread_id);
WaitForSingleObject (channel->data_avail_event, INFINITE); 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); LOCK (channel->mutex);
if (channel->rdp == channel->wrp && !channel->running) if (channel->rdp == channel->wrp && !channel->running)
{ {
@ -479,6 +499,11 @@ g_io_win32_free (GIOChannel *channel)
{ {
GIOWin32Channel *win32_channel = (GIOWin32Channel *) 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) if (win32_channel->buffer)
{ {
CloseHandle (win32_channel->data_avail_event); CloseHandle (win32_channel->data_avail_event);
@ -639,8 +664,33 @@ g_io_win32_fd_close (GIOChannel *channel)
{ {
GIOWin32Channel *win32_channel = (GIOWin32Channel *) 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); 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 static int
@ -734,7 +784,12 @@ g_io_win32_sock_close (GIOChannel *channel)
{ {
GIOWin32Channel *win32_channel = (GIOWin32Channel *) 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); closesocket (win32_channel->fd);
win32_channel->fd = -1;
} }
static int static int

View File

@ -182,6 +182,7 @@ EXPORTS
g_io_channel_win32_poll g_io_channel_win32_poll
g_io_channel_win32_set_debug g_io_channel_win32_set_debug
g_io_channel_write g_io_channel_write
g_io_create_watch
g_list_alloc g_list_alloc
g_list_append g_list_append
g_list_concat g_list_concat
@ -534,6 +535,7 @@ EXPORTS
g_tree_traverse g_tree_traverse
g_tuples_destroy g_tuples_destroy
g_tuples_index g_tuples_index
g_ucs4_to_utf16
g_ucs4_to_utf8 g_ucs4_to_utf8
g_unichar_break_type g_unichar_break_type
g_unichar_digit_value g_unichar_digit_value
@ -560,6 +562,8 @@ EXPORTS
g_unicode_canonical_decomposition g_unicode_canonical_decomposition
g_unicode_canonical_ordering g_unicode_canonical_ordering
g_usleep g_usleep
g_utf16_to_ucs4
g_utf16_to_utf8
g_utf8_find_next_char g_utf8_find_next_char
g_utf8_find_prev_char g_utf8_find_prev_char
g_utf8_get_char g_utf8_get_char
@ -571,6 +575,8 @@ EXPORTS
g_utf8_strlen g_utf8_strlen
g_utf8_strncpy g_utf8_strncpy
g_utf8_to_ucs4 g_utf8_to_ucs4
g_utf8_to_ucs4_fast
g_utf8_to_utf16
g_utf8_validate g_utf8_validate
g_vsnprintf g_vsnprintf
g_win32_closedir g_win32_closedir

View File

@ -1,9 +1,15 @@
#include <errno.h> #include <errno.h>
#include <glib.h> #include <glib.h>
#ifdef G_OS_UNIX
#include <unistd.h> #include <unistd.h>
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef G_OS_WIN32
#include <fcntl.h> /* For _O_BINARY used by pipe() macro */
#endif
#define ITERS 10000 #define ITERS 10000
#define INCREMENT 10 #define INCREMENT 10
#define NTHREADS 4 #define NTHREADS 4

View File

@ -22,6 +22,7 @@ TESTS = \
gio-test.exe \ gio-test.exe \
hash-test.exe \ hash-test.exe \
list-test.exe \ list-test.exe \
mainloop-test.exe\
markup-test.exe \ markup-test.exe \
node-test.exe \ node-test.exe \
queue-test.exe \ queue-test.exe \
@ -35,7 +36,8 @@ TESTS = \
thread-test.exe \ thread-test.exe \
threadpool-test.exe\ threadpool-test.exe\
tree-test.exe \ tree-test.exe \
type-test.exe type-test.exe \
unicode-encoding.exe
all: $(TESTS) all: $(TESTS)

View File

@ -22,6 +22,7 @@ TESTS = \
gio-test.exe \ gio-test.exe \
hash-test.exe \ hash-test.exe \
list-test.exe \ list-test.exe \
mainloop-test.exe\
markup-test.exe \ markup-test.exe \
node-test.exe \ node-test.exe \
queue-test.exe \ queue-test.exe \
@ -36,7 +37,8 @@ TESTS = \
thread-test.exe \ thread-test.exe \
threadpool-test.exe\ threadpool-test.exe\
tree-test.exe \ tree-test.exe \
type-test.exe type-test.exe \
unicode-encoding.exe
all : $(TESTS) all : $(TESTS)

View File

@ -192,7 +192,13 @@ process (gint line,
gint n_chars; gint n_chars;
gchar *utf8_result; 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))) NULL, &bytes_written, NULL)))
{ {
fail ("line %d: could not convert to UTF-16 via g_convert\n", line); 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 */ 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; return;
} }
else else
@ -315,7 +321,7 @@ main (int argc, char **argv)
if (!srcdir) if (!srcdir)
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); g_file_get_contents (testfile, &contents, NULL, &error);
if (error) if (error)
@ -332,10 +338,10 @@ main (int argc, char **argv)
p++; p++;
end = p; end = p;
while (*end && *end != '\n') while (*end && (*end != '\r' && *end != '\n'))
end++; end++;
if (!*p || *p == '#' || *p == '\n') if (!*p || *p == '#' || *p == '\r' || *p == '\n')
goto next_line; goto next_line;
tmp = g_strstrip (g_strndup (p, end - p)); tmp = g_strstrip (g_strndup (p, end - p));
@ -401,6 +407,8 @@ main (int argc, char **argv)
next_line: next_line:
p = end; p = end;
if (*p && *p == '\r')
p++;
if (*p && *p == '\n') if (*p && *p == '\n')
p++; p++;