I managed to reproduce the problem you saw with gtk-vnc and windows hanging. With the glib IO debug turned up high I can see it is treating the FD as a file handle, rather than a socket - which is to be expected because gnulib is wrapping winsock to give back real FDs. Unfortunately glib is on crack, and for file handles it implements IO waits by having a background thread for each file handle that sits in a read/write call forever, and sets flags. To quote the docs "If you have created a GIOChannel for a file descriptor and started watching (polling) it, you shouldn't call read() on the file descriptor. This is because adding polling for a file descriptor is implemented in GLib on Windows by starting a thread that sits blocked in a read() from the file descriptor most of the time. All reads from the file descriptor should be done by this internal GLib thread. Your code should call only g_io_channel_read(). " This is just epic fail when combined with what we want todo. Making gtk-vnc use g_io_channel_read() instead didn't work either. I think the glib thread concept simply doesn't work for FDs which are aliases for sockets. So I've tried a atch which creates an IO channel using g_io_channel_win32_new_socket(_get_osfhandle(fd)) to explicitly make glib treat it as a socket, and avoid the thread insanity. Slightly nasty because we're reversing gnulibs magic by translating the FD back into a socket, but empirically it seems to work better for me. I've not yet got it to hang with this patch. I also needed to make our read/write functions use the 'fd' in the gvnc struct, instead of fetching it from the IOChannel object. Let me know if this patch works for you too.... Daniel diff --git a/src/gvnc.c b/src/gvnc.c --- a/src/gvnc.c +++ b/src/gvnc.c @@ -347,7 +347,6 @@ static int gvnc_zread(struct gvnc *gvnc, static int gvnc_read(struct gvnc *gvnc, void *data, size_t len) { - int fd = g_io_channel_unix_get_fd(gvnc->channel); char *ptr = data; size_t offset = 0; @@ -380,7 +379,7 @@ static int gvnc_read(struct gvnc *gvnc, ret = -1; } } else - ret = recv (fd, gvnc->read_buffer, 4096, 0); + ret = recv (gvnc->fd, gvnc->read_buffer, 4096, 0); if (ret == -1) { switch (errno) { @@ -422,7 +421,6 @@ static int gvnc_read(struct gvnc *gvnc, static void gvnc_flush(struct gvnc *gvnc) { - int fd = g_io_channel_unix_get_fd(gvnc->channel); size_t offset = 0; while (offset < gvnc->write_offset) { int ret; @@ -439,7 +437,7 @@ static void gvnc_flush(struct gvnc *gvnc ret = -1; } } else - ret = send (fd, + ret = send (gvnc->fd, gvnc->write_buffer+offset, gvnc->write_offset-offset, 0); if (ret == -1) { @@ -490,11 +488,10 @@ static ssize_t gvnc_tls_push(gnutls_tran const void *data, size_t len) { struct gvnc *gvnc = (struct gvnc *)transport; - int fd = g_io_channel_unix_get_fd(gvnc->channel); int ret; retry: - ret = write(fd, data, len); + ret = write(gvnc->fd, data, len); if (ret < 0) { if (errno == EINTR) goto retry; @@ -508,11 +505,10 @@ static ssize_t gvnc_tls_pull(gnutls_tran void *data, size_t len) { struct gvnc *gvnc = (struct gvnc *)transport; - int fd = g_io_channel_unix_get_fd(gvnc->channel); int ret; retry: - ret = read(fd, data, len); + ret = read(gvnc->fd, data, len); if (ret < 0) { if (errno == EINTR) goto retry; @@ -2872,7 +2868,13 @@ gboolean gvnc_open_fd(struct gvnc *gvnc, if (!gvnc_set_nonblock(fd)) return FALSE; - if (!(gvnc->channel = g_io_channel_unix_new(fd))) { + if (!(gvnc->channel = +#ifdef WIN32 + g_io_channel_win32_new_socket(_get_osfhandle(fd)) +#else + g_io_channel_unix_new(fd) +#endif + )) { GVNC_DEBUG ("Failed to g_io_channel_unix_new()\n"); return FALSE; } @@ -2917,7 +2919,13 @@ gboolean gvnc_open_host(struct gvnc *gvn if (!gvnc_set_nonblock(fd)) break; - if (!(chan = g_io_channel_unix_new(fd))) { + if (!(chan = +#ifdef WIN32 + g_io_channel_win32_new_socket(_get_osfhandle(fd)) +#else + g_io_channel_unix_new(fd) +#endif + )) { close(fd); GVNC_DEBUG ("Failed to g_io_channel_unix_new()\n"); break; -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|