Finally, a new and improved IO Channel and condition watch implementation

2000-07-30  Tor Lillqvist  <tml@iki.fi>

	Finally, a new and improved IO Channel and condition watch
	implementation for Win32. Based on code provided by Craig Setera.

	When watching file descriptors, for which there is no select()
	like functionality on Win32 that would work on all Win32 platforms
	for all types of file descriptors (including anonymous pipes), we
	start a new thread that blocks while trying to read from the file
	descriptor. When the read returns, a Win32 Event is signalled that
	the polling routine eventually notices. Meanwhile, the data being
	read is stored in a circular buffer, from where the IO channel's
	read() method picks it up.

	If the buffer fills up the reading thread has to wait for space
	becoming available. For this another Win32 Event is used. The IO
	Channel's read() method signals this when it has read some data
	out of the buffer.

	The separate reader thread(s), and the circular buffer(s) with
	associated events mean lots of possibilities for fun parallellism
	errors. But it seems to work OK, i.e. GIMP runs.

	* gmain.c: Small changes to the Win32 polling function.
	(g_main_win32_get_poll_func): New function. Perhaps it would be a
	good idea to provide this on all platforms.

	* giowin32.c: The bulk of the new implementation.
	(g_io_channel_win32_wait_for_condition): New function. To be used
	where on Unix one does a select() on the channel's fd, like
	libgimp's gimp_extension_process(). Could be provided on all
	platforms.

	* glib.h: Update documentation for IO Channels on Win32. Remove
	the declarations for the as of now obsolete old functions related
	to IO Channels for pipes with "wakeup" messages.

	* glib.def: Some new functions.

	* tests/gio-test.c: New file, to test GIOChannel and main loop.

	* tests/Makefile.am
	* tests/makefile.mingw.in: Add it.
This commit is contained in:
Tor Lillqvist
2000-07-29 20:59:07 +00:00
committed by Tor Lillqvist
parent d33887428e
commit b965bb5db1
19 changed files with 1880 additions and 1420 deletions

View File

@@ -2881,29 +2881,43 @@ void g_main_add_poll (GPollFD *fd,
void g_main_remove_poll (GPollFD *fd);
void g_main_set_poll_func (GPollFunc func);
#ifdef G_OS_WIN32
/* Useful on other platforms, too? */
GPollFunc g_main_win32_get_poll_func (void);
#endif
/* On Unix, IO channels created with this function for any file
* descriptor or socket.
*
* On Win32, use this only for plain files opened with the MSVCRT (the
* Microsoft run-time C library) _open(), including file descriptors
* 0, 1 and 2 (corresponding to stdin, stdout and stderr).
* Actually, don't do even that, this code isn't done yet.
* On Win32, use this only for files opened with the MSVCRT (the
* Microsoft run-time C library) _open() or _pipe, including file
* descriptors 0, 1 and 2 (corresponding to stdin, stdout and stderr).
*
* The term file descriptor as used in the context of Win32 refers to
* the emulated Unix-like file descriptors MSVCRT provides.
* the emulated Unix-like file descriptors MSVCRT provides. The native
* corresponding concept is file HANDLE. There isn't as of yet a way to
* get GIOChannels for file HANDLEs.
*/
GIOChannel* g_io_channel_unix_new (int fd);
gint g_io_channel_unix_get_fd (GIOChannel *channel);
#ifdef G_OS_WIN32
GLIB_VAR guint g_pipe_readable_msg;
#define G_WIN32_MSG_HANDLE 19981206
/* This can be used to wait until a channel is readable. On Unix you
* would do a select() on the fd of the channel. This should probably
* be replaced by something for all platforms?
*/
gint g_io_channel_win32_wait_for_condition (GIOChannel *channel,
GIOCondition condition,
gint timeout);
/* This is used to add polling for Windows messages. GDK (GTk+) programs
* should *not* use this. (In fact, I can't think of any program that
* would want to use this, but it's here just for completeness's sake.
* should *not* use this.
*/
void g_main_poll_win32_msg_add(gint priority,
GPollFD *fd,
@@ -2912,40 +2926,16 @@ void g_main_poll_win32_msg_add(gint priority,
/* An IO channel for Windows messages for window handle hwnd. */
GIOChannel *g_io_channel_win32_new_messages (guint hwnd);
/* An IO channel for an anonymous pipe as returned from the MSVCRT
* _pipe(), with no mechanism for the writer to tell the reader when
* there is data in the pipe.
*
* This is not really implemented yet.
/* An IO channel for C runtime (emulated Unix-like) file
* descriptors. Identical to g_io_channel_unix_new above.
*/
GIOChannel *g_io_channel_win32_new_pipe (int fd);
/* An IO channel for a pipe as returned from the MSVCRT _pipe(), with
* Windows user messages used to signal data in the pipe for the
* reader.
*
* fd is the file descriptor. For the write end, peer is the thread id
* of the reader, and peer_fd is his file descriptor for the read end
* of the pipe.
*
* This is used by the GIMP, and works.
*/
GIOChannel *g_io_channel_win32_new_pipe_with_wakeups (int fd,
guint peer,
int peer_fd);
void g_io_channel_win32_pipe_request_wakeups (GIOChannel *channel,
guint peer,
int peer_fd);
void g_io_channel_win32_pipe_readable (int fd,
guint offset);
GIOChannel* g_io_channel_win32_new_fd (int fd);
/* Get the C runtime file descriptor of a channel. */
gint g_io_channel_win32_get_fd (GIOChannel *channel);
/* An IO channel for a SOCK_STREAM winsock socket. The parameter is
* actually a SOCKET.
/* An IO channel for a SOCK_STREAM winsock socket. The parameter should
* be a SOCKET.
*/
GIOChannel *g_io_channel_win32_new_stream_socket (int socket);