Re: windows [Re: Review of gnio, round 2]



Alexander Larsson wrote:
> The not-possible-to-read-non-blocking thing only affects
> g_socket_new_from_fd(), so Its not a horrible problem. Although I agree
> that its kinda weird. Its clearly possible to implement blocking mode on
> win32 purely on the gsocket.c side, which would make GSocket behave
> similar on win32 and unix, however things using g_socket_get_fd() to do
> platform specific things may be surprised when their blocking sockets
> return EWOULDBLOCK.

But g_socket_get_fd() already exposes differences between unix and
windows (the returned fd is a totally different kind of thing on the two
platforms), so once you call g_socket_get_fd() you almost certainly
already need to be doing separate unix and windows code (if you care
about supporting both platforms), so one more difference is ok.
(Obviously we'd have to explicitly document it though.)

Alternatively, we could make the unix implementations of
g_socket_condition_check(), etc, force the socket into non-blocking mode
just like the windows ones do. The way it is now, portable code needs to
behave as though this is the case anyway.

Or, we could force the underlying sockets to be non-blocking on both
unix and windows, which might be nicer than only doing that on Windows
because there'd be less platform-specific code. (FWIW, NSS does this,
although I'm not sure if it's because of winsock or something else.)

>> g_socket_set_reuse_address:

> I thought about this some more, and I think its perhaps not such a good
> idea to always set it. For *server* sockets its generally always safe to
> set it, since the chances of problems is low. We can run into problem is
> another connection has the same (source ip, source port, dest ip, dest
> port) tuple, which is unlikely even if dest ip and port is reused.
> 
> However, for a client socket, i think there is a potential for two
> consecutive connections to one dest ip/port with SO_REUSEADDR set to get
> the same source port and thus confuse the old connection and the new.

OK. On the server side though, this is really one of those "unbreak my
program please" APIs. It's not merely "always safe" to set it, it's
virtually always *much better* to set it, and if someone isn't setting
it, it's probably because they don't know about it, not because they
don't want it.

I was going to say "we could make g_socket_listen() set it" but
actually, you need to do it before calling bind(). I'm not really
familiar with the use cases of bind() on client sockets, but it  seems
like probably if the application is trying to bind to a specific local
port, even for a client socket, then it probably really does want that
port, so setting SO_REUSEADDR in g_socket_bind() even in the client case
should be ok. Alternatively, maybe g_socket_bind() could just take a
flag saying whether or not to set SO_REUSEADDR, or else
g_socket_listen() could be modified to do both bind() and listen() (and
SO_REUSEADDR), and then g_socket_bind() would be only for the
client-side case and would not set SO_REUSEADDR. (This moves a little
further from the underlying API, but it's always seemed a little
pointless to me to have bind and listen be separate syscalls anyway...)

-- Dan


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