Re: BSD sockets: recv with MSG_WAITALL should return EWOULDBLOCK?
- From: "Alex Fraser" <me@xxxxxxxxxxx>
- Date: Sat, 23 Dec 2006 11:13:45 -0000
"Rainer Weikusat" <rainer.weikusat@xxxxxxxxx> wrote in message
news:87ac1ha7uz.fsf@xxxxxxxxxxxxxxxxxxxx
"Alex Fraser" <me@xxxxxxxxxxx> writes:
"Rainer Weikusat" <rainer.weikusat@xxxxxxxxx> wrote:
"Alex Fraser" <me@xxxxxxxxxxx> writes:
It seems to me that MSG_WAITALL does not make sense on non-blocking
sockets. (I am not convinced it is much use for blocking sockets
either.)
It is useful for bulk downloads.
...but not much else.
For a start, either you must be expecting the sender to send at least as
many bytes as the size argument to recv() or to close the connection
after sending. So MSG_WAITALL has strictly limited applicability.
This sounds a lot like 'it is only useful if you specified the flag
because it would be useful and it wasn't, for instance, generated by a
call to random(3)'. Which seems pretty obvious to me.
I said I wasn't convinced MSG_WAITALL was much use. Part of that is the fact
that you can't possibly use it in many cases. Yes, that is obvious; I was
just being explicit.
Even if the above is satisfied, MSG_WAITALL can harm throughput if the
size passed to recv() is "too large" and you are performing some kind of
stream processing (for instance, decompressing it).
And this sounds like 'if you are using a buffer size that doesn't
match some unspecified restrictions some postprocessing code may have
[...]
I think you completely missed the point here. Suppose you have a simple loop
like this:
while ((n = recv(s, buf, len, MSG_WAITALL)) > 0)
consume(buf, n);
Where consume() implements an algorithm which runs in O(n) time. In
practice, of course, there will be some per-call overhead. Assume consume()
can process data faster than it can possibly need to (eg it runs at 20MB/s
but the input is coming over a 100Mbit/s link).
Clearly, the greater the value of len, the better the efficiency (ie
clocks/byte) will be because there are fewer kernel/userspace transitions
due to fewer recv() calls, and of course, similar applies to the per-call
overhead from consume().
But beyond some value of len, you will eventually reach a (system-dependent)
point where throughput starts to reduce, because the kernel buffers will
fill up while consume() is running. That is, len can be "too large". But how
large is too large?
Assuming your application processes data fast enough, you can expect
recv to return for each 'link-layer PDU' (eg ethernet frame) received
unless the kernel handles TCP PSH somehow (at least Linux doesn't).
The above is only true if the delay between when the thread blocked in
recv() becomes ready to run (the relevant receive buffer becomes
non-empty) and actually running (a CPU becomes available) is always
small.
Technically, this is not correct. It doesn't matter if the delay is
small or large, the process must just be able to process incoming
frames in real time.
You snipped the important bit, perhaps because once again you missed the
point. This is roughly what I think could (depending on various factors)
happen if the delay is large:
1. The application calls recv() supplying a large buffer but without
specifying MSG_WAITALL. No data is available so the thread sleeps.
2. A frame arrives causing data to be queued to the socket buffer. The
thread becomes ready-to-run.
3. Another frame arrives and more data is queued to the socket buffer. (And
perhaps another, etc.)
4. The thread runs; all available data is copied to the user buffer, then
recv() returns.
This is getting closer to what would happen if you used MSG_WAITALL, ie the
relative gain in efficiency is reduced on a loaded system.
I haven't made any new points in this post, just - hopefully - clarified the
points I was trying to make before. Unless you actually address them I think
we'll have to call it a day and agree to disagree :).
Alex
.
- Follow-Ups:
- Re: BSD sockets: recv with MSG_WAITALL should return EWOULDBLOCK?
- From: David Schwartz
- Re: BSD sockets: recv with MSG_WAITALL should return EWOULDBLOCK?
- From: Rainer Weikusat
- Re: BSD sockets: recv with MSG_WAITALL should return EWOULDBLOCK?
- References:
- BSD sockets: recv with MSG_WAITALL should return EWOULDBLOCK?
- From: softwaredoug
- Re: BSD sockets: recv with MSG_WAITALL should return EWOULDBLOCK?
- From: Alex Fraser
- Re: BSD sockets: recv with MSG_WAITALL should return EWOULDBLOCK?
- From: Rainer Weikusat
- Re: BSD sockets: recv with MSG_WAITALL should return EWOULDBLOCK?
- From: Alex Fraser
- Re: BSD sockets: recv with MSG_WAITALL should return EWOULDBLOCK?
- From: Rainer Weikusat
- BSD sockets: recv with MSG_WAITALL should return EWOULDBLOCK?
- Prev by Date: Re: forkpty() on Solaris
- Next by Date: Re: multiprocess mmap'd space and condition-like variables (clarification please).
- Previous by thread: Re: BSD sockets: recv with MSG_WAITALL should return EWOULDBLOCK?
- Next by thread: Re: BSD sockets: recv with MSG_WAITALL should return EWOULDBLOCK?
- Index(es):
Relevant Pages
|