On 14/12/11 05:20, Reid Wightman wrote:
> Sam Duncan wrote in post #1036445:
>
>> What happens if you set non-blocking on the socket and try to catch an
>> exception on the recv?
>>
>> require 'fcntl'
>> ...
>>
>> s = UDPSocket.new
>>
>> s.fcntl(Fcntl::F_SETFL, s.fcntl(Fcntl::F_GETFL) | Fcntl::O_NONBLOCK)
>> ...
>> begin
>>
>>     packet, from = s.recvfrom(2048,0)
>>
>> rescue StandardError =>  e
>>     puts "Waarg: #{e}"
>>     next
>> end
>> ...
>>
> Hi Sam -
>
> Thanks for the help.
>
> I am confused, because my program still blocks on the call to
> s.recvfrom().  I tossed a puts before and after the 's.recvfrom()' call
> and sure enough, it is still pausing for 5 seconds inside of the try
> block.  This in spite of the O_NONBLOCK.  And for sanity I did a few
> other printy things to be sure that my program is using the modified
> version of the library.
>
> Is there any known goofiness to ruby 1.8.7's IO not working correctly?
> The behavior that I'm seeing seems really...odd.
>
> Thanks again,
> Reid

And you said that changing the recv buffer size (2**16) made no 
difference? How about specifying Socket::MSG_TRUNC in the flags to see 
if the whole datagram didn't make it (man recv(2)/ recvfrom(2))? Or 
maybe try reading the header (I read it is four bytes) to find the data 
length and then a subsequent read for the rest based on that? Sorry, I'm 
clutching at straws, but I'm curious to see what you find. I found some 
old forum posts with people discussing non-blocking UPD sockets in Ruby, 
but they gave up and used event machine before the issue was resolved 
which is a shame.

Looking at s_recvfrom and s_recvfrom_nonblock in socket.c the main 
difference appears to be that the non-block version sets MSG_DONTWAIT if 
defined, and then uses  rb_io_set_nonblock from io.c to do the fcntl 
shuffle. The blocking version has a retry loop which sits in 
rb_io_wait_readable on the socket fd. I would definitely use the 
nonblock one when fiddling around just to rule out ever getting into 
that rb_io_wait_readable which is just another select.

For what it is worth, neither of those functions appear to have changed 
between ruby-1.8.6-p420, ruby-1.8.7-p352, and ruby-1.9.3-p0.

Sam