Rework the changes to needed to pass mainloop-test. Now we don't need to

2001-01-09  Tor Lillqvist  <tml@iki.fi>

	* giowin32.c (create_reader_thread): Rework the changes to
	needed to pass mainloop-test. Now we don't need to call
	TerminateThread() after all, which is a relief, as the docs
	have a BIG RED WARNING SIGN about using that API. Instead,
	when closing a fd channel that has a reader thread running,
	just mark it as non-running and additionally mark the fd as
	ripe for closing. When the reader thread hopefully eventually
	gets something (and EOF or some actual data), it will note
	that it shouldn't be running, break out of the loop, and close
	the fd.

	The socket channel closing code should probably be changed
	similarily, but that will have to wait until I have a test case.

	(g_pipe_readable_msg, g_io_channel_win32_new_pipe,
	g_io_channel_win32_new_pipe_with_wakeups,
	g_io_channel_win32_pipe_request_wakeups,
	g_io_channel_win32_pipe_readable): Remove these, have been
	obsolete for some time.

	* glib.def: Update.
This commit is contained in:
Tor Lillqvist 2001-01-09 20:46:49 +00:00 committed by Tor Lillqvist
parent 78231a4b25
commit 9d27e6b7d5
12 changed files with 234 additions and 154 deletions

View File

@ -1,5 +1,24 @@
2001-01-09 Tor Lillqvist <tml@iki.fi>
* giowin32.c (create_reader_thread): Rework the changes needed to
pass mainloop-test. Now we don't need to call TerminateThread()
after all, which is a relief, as the docs have a BIG RED WARNING
SIGN about using that API. Instead, when closing a fd channel that
has a reader thread running, just mark it as non-running and
additionally mark the fd as ripe for closing. When the reader
thread hopefully eventually gets something (and EOF or some actual
data), it will note that it shouldn't be running, break out of the
loop, and close the fd.
The socket channel closing code should probably be changed
similarily, but that will have to wait until I have a test case.
(g_pipe_readable_msg, g_io_channel_win32_new_pipe,
g_io_channel_win32_new_pipe_with_wakeups,
g_io_channel_win32_pipe_request_wakeups,
g_io_channel_win32_pipe_readable): Remove these, have been
obsolete for some time.
* gutils.c (g_basename, g_dirname): Don't warn about deprecation
on Win32. Code written for GLib 1.2 doesn't have much choice but
to use GLib >= 1.3 on Win32.

View File

@ -1,5 +1,24 @@
2001-01-09 Tor Lillqvist <tml@iki.fi>
* giowin32.c (create_reader_thread): Rework the changes needed to
pass mainloop-test. Now we don't need to call TerminateThread()
after all, which is a relief, as the docs have a BIG RED WARNING
SIGN about using that API. Instead, when closing a fd channel that
has a reader thread running, just mark it as non-running and
additionally mark the fd as ripe for closing. When the reader
thread hopefully eventually gets something (and EOF or some actual
data), it will note that it shouldn't be running, break out of the
loop, and close the fd.
The socket channel closing code should probably be changed
similarily, but that will have to wait until I have a test case.
(g_pipe_readable_msg, g_io_channel_win32_new_pipe,
g_io_channel_win32_new_pipe_with_wakeups,
g_io_channel_win32_pipe_request_wakeups,
g_io_channel_win32_pipe_readable): Remove these, have been
obsolete for some time.
* gutils.c (g_basename, g_dirname): Don't warn about deprecation
on Win32. Code written for GLib 1.2 doesn't have much choice but
to use GLib >= 1.3 on Win32.

View File

@ -1,5 +1,24 @@
2001-01-09 Tor Lillqvist <tml@iki.fi>
* giowin32.c (create_reader_thread): Rework the changes needed to
pass mainloop-test. Now we don't need to call TerminateThread()
after all, which is a relief, as the docs have a BIG RED WARNING
SIGN about using that API. Instead, when closing a fd channel that
has a reader thread running, just mark it as non-running and
additionally mark the fd as ripe for closing. When the reader
thread hopefully eventually gets something (and EOF or some actual
data), it will note that it shouldn't be running, break out of the
loop, and close the fd.
The socket channel closing code should probably be changed
similarily, but that will have to wait until I have a test case.
(g_pipe_readable_msg, g_io_channel_win32_new_pipe,
g_io_channel_win32_new_pipe_with_wakeups,
g_io_channel_win32_pipe_request_wakeups,
g_io_channel_win32_pipe_readable): Remove these, have been
obsolete for some time.
* gutils.c (g_basename, g_dirname): Don't warn about deprecation
on Win32. Code written for GLib 1.2 doesn't have much choice but
to use GLib >= 1.3 on Win32.

View File

@ -1,5 +1,24 @@
2001-01-09 Tor Lillqvist <tml@iki.fi>
* giowin32.c (create_reader_thread): Rework the changes needed to
pass mainloop-test. Now we don't need to call TerminateThread()
after all, which is a relief, as the docs have a BIG RED WARNING
SIGN about using that API. Instead, when closing a fd channel that
has a reader thread running, just mark it as non-running and
additionally mark the fd as ripe for closing. When the reader
thread hopefully eventually gets something (and EOF or some actual
data), it will note that it shouldn't be running, break out of the
loop, and close the fd.
The socket channel closing code should probably be changed
similarily, but that will have to wait until I have a test case.
(g_pipe_readable_msg, g_io_channel_win32_new_pipe,
g_io_channel_win32_new_pipe_with_wakeups,
g_io_channel_win32_pipe_request_wakeups,
g_io_channel_win32_pipe_readable): Remove these, have been
obsolete for some time.
* gutils.c (g_basename, g_dirname): Don't warn about deprecation
on Win32. Code written for GLib 1.2 doesn't have much choice but
to use GLib >= 1.3 on Win32.

View File

@ -1,5 +1,24 @@
2001-01-09 Tor Lillqvist <tml@iki.fi>
* giowin32.c (create_reader_thread): Rework the changes needed to
pass mainloop-test. Now we don't need to call TerminateThread()
after all, which is a relief, as the docs have a BIG RED WARNING
SIGN about using that API. Instead, when closing a fd channel that
has a reader thread running, just mark it as non-running and
additionally mark the fd as ripe for closing. When the reader
thread hopefully eventually gets something (and EOF or some actual
data), it will note that it shouldn't be running, break out of the
loop, and close the fd.
The socket channel closing code should probably be changed
similarily, but that will have to wait until I have a test case.
(g_pipe_readable_msg, g_io_channel_win32_new_pipe,
g_io_channel_win32_new_pipe_with_wakeups,
g_io_channel_win32_pipe_request_wakeups,
g_io_channel_win32_pipe_readable): Remove these, have been
obsolete for some time.
* gutils.c (g_basename, g_dirname): Don't warn about deprecation
on Win32. Code written for GLib 1.2 doesn't have much choice but
to use GLib >= 1.3 on Win32.

View File

@ -1,5 +1,24 @@
2001-01-09 Tor Lillqvist <tml@iki.fi>
* giowin32.c (create_reader_thread): Rework the changes needed to
pass mainloop-test. Now we don't need to call TerminateThread()
after all, which is a relief, as the docs have a BIG RED WARNING
SIGN about using that API. Instead, when closing a fd channel that
has a reader thread running, just mark it as non-running and
additionally mark the fd as ripe for closing. When the reader
thread hopefully eventually gets something (and EOF or some actual
data), it will note that it shouldn't be running, break out of the
loop, and close the fd.
The socket channel closing code should probably be changed
similarily, but that will have to wait until I have a test case.
(g_pipe_readable_msg, g_io_channel_win32_new_pipe,
g_io_channel_win32_new_pipe_with_wakeups,
g_io_channel_win32_pipe_request_wakeups,
g_io_channel_win32_pipe_readable): Remove these, have been
obsolete for some time.
* gutils.c (g_basename, g_dirname): Don't warn about deprecation
on Win32. Code written for GLib 1.2 doesn't have much choice but
to use GLib >= 1.3 on Win32.

View File

@ -1,5 +1,24 @@
2001-01-09 Tor Lillqvist <tml@iki.fi>
* giowin32.c (create_reader_thread): Rework the changes needed to
pass mainloop-test. Now we don't need to call TerminateThread()
after all, which is a relief, as the docs have a BIG RED WARNING
SIGN about using that API. Instead, when closing a fd channel that
has a reader thread running, just mark it as non-running and
additionally mark the fd as ripe for closing. When the reader
thread hopefully eventually gets something (and EOF or some actual
data), it will note that it shouldn't be running, break out of the
loop, and close the fd.
The socket channel closing code should probably be changed
similarily, but that will have to wait until I have a test case.
(g_pipe_readable_msg, g_io_channel_win32_new_pipe,
g_io_channel_win32_new_pipe_with_wakeups,
g_io_channel_win32_pipe_request_wakeups,
g_io_channel_win32_pipe_readable): Remove these, have been
obsolete for some time.
* gutils.c (g_basename, g_dirname): Don't warn about deprecation
on Win32. Code written for GLib 1.2 doesn't have much choice but
to use GLib >= 1.3 on Win32.

View File

@ -1,5 +1,24 @@
2001-01-09 Tor Lillqvist <tml@iki.fi>
* giowin32.c (create_reader_thread): Rework the changes needed to
pass mainloop-test. Now we don't need to call TerminateThread()
after all, which is a relief, as the docs have a BIG RED WARNING
SIGN about using that API. Instead, when closing a fd channel that
has a reader thread running, just mark it as non-running and
additionally mark the fd as ripe for closing. When the reader
thread hopefully eventually gets something (and EOF or some actual
data), it will note that it shouldn't be running, break out of the
loop, and close the fd.
The socket channel closing code should probably be changed
similarily, but that will have to wait until I have a test case.
(g_pipe_readable_msg, g_io_channel_win32_new_pipe,
g_io_channel_win32_new_pipe_with_wakeups,
g_io_channel_win32_pipe_request_wakeups,
g_io_channel_win32_pipe_readable): Remove these, have been
obsolete for some time.
* gutils.c (g_basename, g_dirname): Don't warn about deprecation
on Win32. Code written for GLib 1.2 doesn't have much choice but
to use GLib >= 1.3 on Win32.

View File

@ -88,6 +88,9 @@ struct _GIOWin32Channel {
gboolean running; /* Is reader thread running. FALSE if
* EOF has been reached.
*/
gboolean needs_close; /* If the channel has been closed while
* the reader thread was still running.
*/
guint thread_id; /* If non-NULL has a reader thread, or has
* had.*/
HANDLE thread_handle;
@ -123,6 +126,7 @@ g_io_channel_win32_init (GIOWin32Channel *channel)
#endif
channel->buffer = NULL;
channel->running = FALSE;
channel->needs_close = FALSE;
channel->thread_id = 0;
channel->data_avail_event = NULL;
channel->space_avail_event = NULL;
@ -232,17 +236,28 @@ reader_thread (void *parameter)
if (channel->debug)
g_print ("thread %#x: got EOF, rdp=%d, wrp=%d, setting data available\n",
channel->thread_id, channel->rdp, channel->wrp);
if (channel->needs_close)
{
if (channel->debug)
g_print ("thread %#x: channel fd %d needs closing\n",
channel->thread_id, channel->fd);
if (channel->type == G_IO_FILE_DESC)
close (channel->fd);
else if (channel->type == G_IO_STREAM_SOCKET)
closesocket (channel->fd);
channel->fd = -1;
}
SetEvent (channel->data_avail_event);
UNLOCK (channel->mutex);
g_io_channel_unref((GIOChannel *) channel);
#if 0
/* All of the Microsoft docs say we should explicitly
* end the thread...
/* No need to call _endthreadex(), the actual thread starter routine
* in MSVCRT (see crt/src/threadex.c:_threadstartex) calls
* _endthreadex() for us.
*/
_endthreadex(1);
#endif
CloseHandle (channel->thread_handle);
@ -255,21 +270,10 @@ create_reader_thread (GIOWin32Channel *channel,
{
channel->reader = reader;
#if 0
if ((channel->thread_handle =
_beginthreadex (NULL, 0, reader_thread, channel, 0,
&channel->thread_id)) == 0)
(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);
}
@ -672,25 +676,23 @@ g_io_win32_fd_close (GIOChannel *channel)
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);
g_print ("thread %#x: running, marking fd %d for later close\n",
win32_channel->thread_id, win32_channel->fd);
win32_channel->running = FALSE;
win32_channel->needs_close = TRUE;
SetEvent (win32_channel->data_avail_event);
}
else
{
if (win32_channel->debug)
g_print ("closing fd %d\n", win32_channel->fd);
close (win32_channel->fd);
if (win32_channel->debug)
g_print ("closed fd %d, setting to -1\n",
win32_channel->fd);
win32_channel->fd = -1;
}
UNLOCK (win32_channel->mutex);
if (win32_channel->debug)
g_print ("closing fd %d\n", win32_channel->fd);
close (win32_channel->fd);
if (win32_channel->debug)
g_print ("closed fd %d, setting to -1\n",
win32_channel->fd);
win32_channel->fd = -1;
}
static int
@ -842,6 +844,8 @@ g_io_channel_win32_new_messages (guint hwnd)
g_io_channel_init (channel);
g_io_channel_win32_init (win32_channel);
if (win32_channel->debug)
g_print ("g_io_channel_win32_new_messages: hwnd = %ud\n", hwnd);
channel->funcs = &win32_channel_msg_funcs;
win32_channel->type = G_IO_WINDOWS_MESSAGES;
win32_channel->hwnd = (HWND) hwnd;
@ -867,6 +871,8 @@ g_io_channel_win32_new_fd (gint fd)
g_io_channel_init (channel);
g_io_channel_win32_init (win32_channel);
if (win32_channel->debug)
g_print ("g_io_channel_win32_new_fd: fd = %d\n", fd);
channel->funcs = &win32_channel_fd_funcs;
win32_channel->type = G_IO_FILE_DESC;
win32_channel->fd = fd;
@ -890,6 +896,8 @@ g_io_channel_win32_new_stream_socket (int socket)
g_io_channel_init (channel);
g_io_channel_win32_init (win32_channel);
if (win32_channel->debug)
g_print ("g_io_channel_win32_new_stream_socket: socket = %d\n", socket);
channel->funcs = &win32_channel_sock_funcs;
win32_channel->type = G_IO_STREAM_SOCKET;
win32_channel->fd = socket;
@ -960,42 +968,3 @@ g_io_channel_win32_make_pollfd (GIOChannel *channel,
else if (win32_channel->type == G_IO_STREAM_SOCKET)
create_reader_thread (win32_channel, sock_reader);
}
/* This variable and the functions below are present just to be
* binary compatible with old clients... But note that in GIMP, the
* libgimp/gimp.c:gimp_extension_process() function will have to be modified
* anyhow for this new approach.
*
* These will be removed after some weeks.
*/
guint g_pipe_readable_msg = 0;
GIOChannel *
g_io_channel_win32_new_pipe (int fd)
{
return g_io_channel_win32_new_fd (fd);
}
GIOChannel *
g_io_channel_win32_new_pipe_with_wakeups (int fd,
guint peer,
int peer_fd)
{
return g_io_channel_win32_new_fd (fd);
}
void
g_io_channel_win32_pipe_request_wakeups (GIOChannel *channel,
guint peer,
int peer_fd)
{
/* Nothing needed now */
}
void
g_io_channel_win32_pipe_readable (gint fd,
guint offset)
{
/* Nothing needed now */
}

View File

@ -180,11 +180,7 @@ EXPORTS
g_io_channel_win32_make_pollfd
g_io_channel_win32_new_fd
g_io_channel_win32_new_messages
g_io_channel_win32_new_pipe
g_io_channel_win32_new_pipe_with_wakeups
g_io_channel_win32_new_stream_socket
g_io_channel_win32_pipe_readable
g_io_channel_win32_pipe_request_wakeups
g_io_channel_win32_poll
g_io_channel_win32_set_debug
g_io_channel_write
@ -301,7 +297,6 @@ EXPORTS
g_path_get_dirname
g_path_is_absolute
g_path_skip_root
g_pipe_readable_msg
g_print
g_printerr
g_printf_string_upper_bound

View File

@ -88,6 +88,9 @@ struct _GIOWin32Channel {
gboolean running; /* Is reader thread running. FALSE if
* EOF has been reached.
*/
gboolean needs_close; /* If the channel has been closed while
* the reader thread was still running.
*/
guint thread_id; /* If non-NULL has a reader thread, or has
* had.*/
HANDLE thread_handle;
@ -123,6 +126,7 @@ g_io_channel_win32_init (GIOWin32Channel *channel)
#endif
channel->buffer = NULL;
channel->running = FALSE;
channel->needs_close = FALSE;
channel->thread_id = 0;
channel->data_avail_event = NULL;
channel->space_avail_event = NULL;
@ -232,17 +236,28 @@ reader_thread (void *parameter)
if (channel->debug)
g_print ("thread %#x: got EOF, rdp=%d, wrp=%d, setting data available\n",
channel->thread_id, channel->rdp, channel->wrp);
if (channel->needs_close)
{
if (channel->debug)
g_print ("thread %#x: channel fd %d needs closing\n",
channel->thread_id, channel->fd);
if (channel->type == G_IO_FILE_DESC)
close (channel->fd);
else if (channel->type == G_IO_STREAM_SOCKET)
closesocket (channel->fd);
channel->fd = -1;
}
SetEvent (channel->data_avail_event);
UNLOCK (channel->mutex);
g_io_channel_unref((GIOChannel *) channel);
#if 0
/* All of the Microsoft docs say we should explicitly
* end the thread...
/* No need to call _endthreadex(), the actual thread starter routine
* in MSVCRT (see crt/src/threadex.c:_threadstartex) calls
* _endthreadex() for us.
*/
_endthreadex(1);
#endif
CloseHandle (channel->thread_handle);
@ -255,21 +270,10 @@ create_reader_thread (GIOWin32Channel *channel,
{
channel->reader = reader;
#if 0
if ((channel->thread_handle =
_beginthreadex (NULL, 0, reader_thread, channel, 0,
&channel->thread_id)) == 0)
(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);
}
@ -672,25 +676,23 @@ g_io_win32_fd_close (GIOChannel *channel)
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);
g_print ("thread %#x: running, marking fd %d for later close\n",
win32_channel->thread_id, win32_channel->fd);
win32_channel->running = FALSE;
win32_channel->needs_close = TRUE;
SetEvent (win32_channel->data_avail_event);
}
else
{
if (win32_channel->debug)
g_print ("closing fd %d\n", win32_channel->fd);
close (win32_channel->fd);
if (win32_channel->debug)
g_print ("closed fd %d, setting to -1\n",
win32_channel->fd);
win32_channel->fd = -1;
}
UNLOCK (win32_channel->mutex);
if (win32_channel->debug)
g_print ("closing fd %d\n", win32_channel->fd);
close (win32_channel->fd);
if (win32_channel->debug)
g_print ("closed fd %d, setting to -1\n",
win32_channel->fd);
win32_channel->fd = -1;
}
static int
@ -842,6 +844,8 @@ g_io_channel_win32_new_messages (guint hwnd)
g_io_channel_init (channel);
g_io_channel_win32_init (win32_channel);
if (win32_channel->debug)
g_print ("g_io_channel_win32_new_messages: hwnd = %ud\n", hwnd);
channel->funcs = &win32_channel_msg_funcs;
win32_channel->type = G_IO_WINDOWS_MESSAGES;
win32_channel->hwnd = (HWND) hwnd;
@ -867,6 +871,8 @@ g_io_channel_win32_new_fd (gint fd)
g_io_channel_init (channel);
g_io_channel_win32_init (win32_channel);
if (win32_channel->debug)
g_print ("g_io_channel_win32_new_fd: fd = %d\n", fd);
channel->funcs = &win32_channel_fd_funcs;
win32_channel->type = G_IO_FILE_DESC;
win32_channel->fd = fd;
@ -890,6 +896,8 @@ g_io_channel_win32_new_stream_socket (int socket)
g_io_channel_init (channel);
g_io_channel_win32_init (win32_channel);
if (win32_channel->debug)
g_print ("g_io_channel_win32_new_stream_socket: socket = %d\n", socket);
channel->funcs = &win32_channel_sock_funcs;
win32_channel->type = G_IO_STREAM_SOCKET;
win32_channel->fd = socket;
@ -960,42 +968,3 @@ g_io_channel_win32_make_pollfd (GIOChannel *channel,
else if (win32_channel->type == G_IO_STREAM_SOCKET)
create_reader_thread (win32_channel, sock_reader);
}
/* This variable and the functions below are present just to be
* binary compatible with old clients... But note that in GIMP, the
* libgimp/gimp.c:gimp_extension_process() function will have to be modified
* anyhow for this new approach.
*
* These will be removed after some weeks.
*/
guint g_pipe_readable_msg = 0;
GIOChannel *
g_io_channel_win32_new_pipe (int fd)
{
return g_io_channel_win32_new_fd (fd);
}
GIOChannel *
g_io_channel_win32_new_pipe_with_wakeups (int fd,
guint peer,
int peer_fd)
{
return g_io_channel_win32_new_fd (fd);
}
void
g_io_channel_win32_pipe_request_wakeups (GIOChannel *channel,
guint peer,
int peer_fd)
{
/* Nothing needed now */
}
void
g_io_channel_win32_pipe_readable (gint fd,
guint offset)
{
/* Nothing needed now */
}

View File

@ -180,11 +180,7 @@ EXPORTS
g_io_channel_win32_make_pollfd
g_io_channel_win32_new_fd
g_io_channel_win32_new_messages
g_io_channel_win32_new_pipe
g_io_channel_win32_new_pipe_with_wakeups
g_io_channel_win32_new_stream_socket
g_io_channel_win32_pipe_readable
g_io_channel_win32_pipe_request_wakeups
g_io_channel_win32_poll
g_io_channel_win32_set_debug
g_io_channel_write
@ -301,7 +297,6 @@ EXPORTS
g_path_get_dirname
g_path_is_absolute
g_path_skip_root
g_pipe_readable_msg
g_print
g_printerr
g_printf_string_upper_bound