+ g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+ g_io_channel_error_from_errno (errno),
+ g_strerror (errno));
+ return G_IO_STATUS_ERROR;
+ }
+
+ return G_IO_STATUS_NORMAL;
+}
+
+static GIOStatus
+g_io_win32_fd_close (GIOChannel *channel,
+ GError **err)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+ if (win32_channel->debug)
+ g_print ("g_io_win32_fd_close: thread=%#x: fd=%d\n",
+ win32_channel->thread_id,
+ win32_channel->fd);
+ EnterCriticalSection (&win32_channel->mutex);
+ if (win32_channel->running)
+ {
+ if (win32_channel->debug)
+ 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;
+ if (win32_channel->direction == 0)
+ SetEvent (win32_channel->data_avail_event);
+ else
+ SetEvent (win32_channel->space_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;
+ }
+ LeaveCriticalSection (&win32_channel->mutex);
+
+ /* FIXME error detection? */
+
+ return G_IO_STATUS_NORMAL;
+}
+
+static GSource *
+g_io_win32_fd_create_watch (GIOChannel *channel,
+ GIOCondition condition)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+ GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
+ GIOWin32Watch *watch = (GIOWin32Watch *)source;
+
+ watch->channel = channel;
+ g_io_channel_ref (channel);
+
+ watch->condition = condition;
+
+ if (win32_channel->data_avail_event == NULL)
+ create_events (win32_channel);
+
+ watch->pollfd.fd = (gintptr) win32_channel->data_avail_event;
+ watch->pollfd.events = condition;
+
+ if (win32_channel->debug)
+ g_print ("g_io_win32_fd_create_watch: channel=%p fd=%d condition={%s} event=%p\n",
+ channel, win32_channel->fd,
+ condition_to_string (condition), (HANDLE) watch->pollfd.fd);
+
+ EnterCriticalSection (&win32_channel->mutex);
+ if (win32_channel->thread_id == 0)
+ {
+ if (condition & G_IO_IN)
+ create_thread (win32_channel, condition, read_thread);
+ else if (condition & G_IO_OUT)
+ create_thread (win32_channel, condition, write_thread);