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...


Bill



Reply via email to