apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Bill Stoddard <b...@wstoddard.com>
Subject Re: Win32 apr_sockets; Random notes from the 'oh, duh' department
Date Wed, 23 Apr 2003 22:24:51 GMT
William A. Rowe, Jr. wrote:
> Folks, 
>   we have a number of real issues with the win32 implementation of sockets
> which I think I can fix over the next day or so, but I'm just dropping off this
> note early enough for folks to bitch^H^H^H^H^H comment.
>   Serious Problem #1: Blocking Socket, apr_sendv() invokes WSASend()
> with NULL completion arguments... according to WinSock2 this should
> be a sync, blocking send.  Put a huge (4MB), mmap'ed region into that 
> iovec, and it will be sent - BUT IT IS SENT ASYNC!  So later we close the
> socket and the transmission is aborted.
Humm...  I'll ruminate on this some... there may be another solution. 
You sure the WSASend call is not returning a timeout expiration?

>   Solution?  Apparently we just can't trust sync send/recv, and I guess
> it is time to simply surrender and make them all async with a completion
> event, irrespective of timeouts.  Then wait on that event INFINITE or by 
> the so_timeout value.
>   Question; do we simply use the socket itself as the event handle?  

Should be fine as long as multiple threads never attempt to touch the 
socket at the same time. apr_sendfile uses the socket as the event 
handle and AFAIK it has never caused a problem.

> Or do we create one event for each socket that we can later use for all
> sorts of goodness such as a WSAAsyncSelect()-style poll?  Two threads
> won't be looking at the same socket, so I think an event handle in each
> apr_socket_t would be useful.
I'd prefer to not use a seperate event handle (for performance reasons) 
unless we have a clear demonstrated fully thought out need to. MHO.
>   Serious Problem #2: Win32 doesn't support socket timeouts.  We are
> using raw WSASend/WSARecv, blocking.  This just isn't good.

Sure it does, just not the same way as most unix systems. Unix uses 
nonblocking i/o followed by a select to do timeout. This is horribly 
inefficient on Windows where sys call overhead is high.  Windows uses 
the builtin setsockopt(SO_RCVTIMEOUT) timeout mechanisms (which are part 
of the BSD socket spec but is not implemented on Unix).  If, as you are 
reporting, WSA* calls are not really working as they should, then we 
should probably just do them async and wait for the io completion.

>   Solution?  Same as for #1 above.
>   Serious Problem #3: Using WaitForSingleObject() with our 'socket'
> timeout value is rather bogus - it would measure the total elapsed time,
> not the interval between packet transmissions.
>   Solution?  Well, if WinSock2 had some sort of 'progress' indication, bytes
> sent or received so far for a completion-based request - then we could just
> sample and assure ourselves that something had happened.  As it is we
> just can't do that.  Effectively, it looks like any huge send over a slow wire
> will be timed out based on any sane setting for a timeout value.

That should not be the case. Last time I checked, I though we set the 
timeout then sent 64K (?) chunks then reset the timeout for the next 64k 
chunk. This is -eaxactly- what 1.3 does on Unix (where signals are used 
as the timeout mechanism). This has someone changed that w/o my 
noticing? I'll check later...


View raw message