Opened 12 years ago
Closed 12 years ago
#9734 closed bug (fixed)
Receiving from a nonblocking socket causes "Operation timed out" error
Reported by: | markh | Owned by: | phoudoin |
---|---|---|---|
Priority: | normal | Milestone: | R1 |
Component: | Network & Internet/UDP | Version: | R1/Development |
Keywords: | Cc: | ||
Blocked By: | Blocking: | ||
Platform: | All |
Description
When trying to receive data from a nonblocking socket, I get an "Operation timed out" error, while I am expecting a EWOULDBLOCK error as there is no data to read. Changing the socket to blocking does block as expected. I expanded my test case from #9678 and attached it to this ticket.
This happens with href45525.
Attachments (1)
Change History (6)
by , 12 years ago
Attachment: | socket_test_send_double_recv_1_socket.c added |
---|
comment:1 by , 12 years ago
follow-up: 3 comment:2 by , 12 years ago
Except if BeOS handled a zero B_ABSOLUTE_TIMEOUT as a zero relative, which I doubt, I'm for fixing DatagramSocket template timeout handling.
I wonder why absolute timeout is used instead of relative one anyway?
follow-up: 4 comment:3 by , 12 years ago
Replying to phoudoin:
I wonder why absolute timeout is used instead of relative one anyway?
Usually it is necessary to convert relative timeouts to absolute ones, so that syscall aren't restarted with the full timeout each time. That might not be relevant here. Another reason (actually the same, just generalized) to convert to absolute is, if there are potentially multiple waits ahead.
I think the best way to do the timeout conversion is to always pass on a (bigtime_t, uint32)
pair (make it a helper class, if you want something more handy to pass around). In the zero timeout case the conversion result would then be (0, B_RELATIVE_TIMEOUT)
and the correct return code would be generated automatically. I would handle a 0 absolute timeout specially only if BeOS does. I don't have a BeOS installation at hand ATM, though.
An alternative for your case might be to check the return code and, if it is B_TIMED_OUT
convert to B_WOULD_BLOCK
, if the timeout is 0. Not that elegant, but IIRC other code does it the same way.
comment:4 by , 12 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
Replying to bonefish:
Usually it is necessary to convert relative timeouts to absolute ones, so that syscall aren't restarted with the full timeout each time. That might not be relevant here.
In fact, it is. Thanks for the explanation.
An alternative for your case might be to check the return code and, if it is
B_TIMED_OUT
convert toB_WOULD_BLOCK
, if the timeout is 0. Not that elegant, but IIRC other code does it the same way.
I guess that the way to go, indeed. I'll do that, except if someone does it before.
comment:5 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Sorry, didn't notice you assigned it to yourself already! In any case, it's fixed in hrev45609 - I just use B_RELATIVE_TIMEOUT in case the timeout is 0.
The following code pieces are important here:
IOW either the code at 2.) must not use B_ABSOLUTE_TIMEOUT when the timeout is actually zero, or the kernel should treat absolute timeout as relative if the timeout is zero.
Opinions anyone? Maybe we should find out what BeOS did here, and stay compatible (which probably means changing 2.)).