Re: Win32 Glib 2.8.x g_io_channel issues (receiving window messages on socket io channel)



There are some problems both in your code, and in giowin32.c.

For efficiency, your code should not read just one byte at a time in
the callback. It should read in bigger chunks, and as much as possible
in a loop, until it gets a WSAEWOULDBLOCK or an EOF. If it did this,
it would probably also work with giowin32.c as it currently is
written.

Your code frees the GaimFetchUrlData twice. I don't recall the exact
details, but the call to destroy_fetch_url_data() in gaim_url_fetch()
is unnecessary, if gaim_proxy_connect() returns failure it has already
been called.

You send a HTTP/1.1 request to the server, meaning it defaults to
using keepalive. You should also send Connection: close, or the server
won't necessarily close it. Or you could shutdown the socket from your
end with shutdown(sock,SD_SEND), then the server will presumably also
close its end after sending the data.

Anyway, the handling of closed sockets in giowin32.c does not emulate
exactly how it works out on Unix. On Win32, the event for a socket
(see MSDN docs for WSAEventSelect() and WSAEnumNetworkEvents()) will
fire with FD_CLOSE only once after the remote end has shut down the
connection.

g_io_win32_check() currently works in such a way that the dispatch
function will be invoked with G_IO_HUP only once after that
(additionally G_IO_IN, if FD_READ also was set). If the user callback
then reads less data than available, the callback will continue to be
invoked with just G_IO_IN.

After there is no longer any data to read, the event will not fire,
and no more callbacks will be invoked. I.e., no more callbacks with
(only) G_IO_HUP. On Unix, apparently a callback will be called
repeatedly with G_IO_IN as long as the socket is polled if the remote
end has shut down the connection?

giowin32.c presumably should be fixed at least so that the G_IO_HUP
indication will "stick". After a FD_CLOSE has been seen, G_IO_HUP
would always be set in combination with G_IO_IN in the callbacks.

Maybe even the socket's event should be forced to the signalled state
after a FD_CLOSE is received, so that g_poll() would continuously
notice it, and the callback continuously invoked with G_IO_HUP, until
the watch is removed? Hmm.

Note though, that code that uses the higher-level gdk_input_add()
functionality and not GIOChannels only has a GdkInputCondition to look
at, not a GIOCondition. Thus it can't distinguish between G_IO_IN and
G_IO_HUP, as both are combined into GDK_INPUT_READ.

Anyway, what you originally asked about, the extraneous calls to
WSAEnumNetworkEvents() indeed seem to be quite unnecessary, and are
easy to get rid of. Will do that. Just those extra calls shouldn't
affect how the code works, though. To make this work somewhat more
like on Unix, changes as outlined above are needed to giowin32.c.

--tml




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]