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

On Tue, 2005-11-15 at 22:08 +0200, Tor Lillqvist wrote:
> (Follow-up to a message in gtk-app-devel-list, see there for
> background.)
>  > Anyway, the handling of [shutdown by the other end] 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.
> What semantics does GLib promise with respect to G_IO_IN vs. G_IO_HUP?
> Or what can apps reasonably expect? In what cases does poll() set
> POLLHUP on Unix (when polling sockets)?  After the remote end has
> shutdown for writing, or closed a TCP connection, will the callback
> from giounix indicate G_IO_HUP, or just G_IO_IN?

[ warning: from memory ]

In general, on systems new enough to have poll(), a socket will
indicate HUP rather than IN when it has been closed on the other
end. poll() and select() are about *state* rather than *events*
so once a socket returns HUP, it will continue to return HUP.

On the other hand, if a system is emulating poll() with select() -
which was the standard state 5 years ago and I think is still
the case on OS X, then you'll just get IN, and have to notice the
zero length read.

In general, if you are writing code that you want to be portable,
what you should do is add a watch on G_IO_IN | G_IO_HUP, and 
in that callback just always do a read. If the read is zero length,
then the socket has been closed, so cleanup, close the socket,
and return FALSE to remove the watch.


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