I am developing a multiplatform Ruby program that is supposed to connect via USB to a serial device. First I was using the serialport gem (1.0.4), but then I ran into some strange problems and had to drop it. I then proceeded to communicate via Ruby's IO class, as follows:
@port = IO.new IO.sysopen(path, mode), mode
Communication via syswrite and sysread is perfect both in Linux as Windows.
With the communication done, I tried setting up timeouts so that the program won't hang if any desync occurs. All done on the Linux side with timeout.rb, but Windows won't get me control of the interpreter again after calling any IO read method (sysread, getc, gets, getbyte... I tried them all!).
I experimented with Terminator, but it wouldn't even run, throwing argument exceptions instead of timing out -- even in Linux!:
require 'terminator'
Terminator.terminate 2 do
sleep 4
end
produces:
/var/lib/gems/1.9.1/gems/terminator-0.4.4/lib/terminator.rb:164: Use RbConfig instead of obsolete and deprecated Config.
ArgumentError: wrong number of arguments (1 for 0)
from /var/lib/gems/1.9.1/gems/terminator-0.4.4/lib/terminator.rb:127:in `block in terminate'
from (irb):12:in `call'
from (irb):12:in `sleep'
from (irb):12:in `block in irb_binding'
from /var/lib/gems/1.9.1/gems/terminator-0.4.4/lib/terminator.rb:134:in `call'
from /var/lib/gems/1.9.1/gems/terminator-0.4.4/lib/terminator.rb:134:in `terminate'
from (irb):11
from /usr/bin/irb:12:in `<main>'
As SystemTimer relies on UNIX signals and doesn't work on Windows (it simply wraps timeout.rb), I am stuck with a multiplatform program that would just eternally hang when running on Windows, although just fine on Linux.
Is there any way I could set timeouts on serial port reading on Windows? Perhaps a win32api call?
Thank you for your time. :)
Edit:
I believe I found a way around the problem, although it really stinks.
instead of
Timeout::timeout 0.5 do
gets
end
I tried
begin
Timeout::timeout 0.5 do
Thread.new do
gets
end.join
end
rescue
"Expired :)"
end
and it seems to be fine on IRB.
I'm going to implement and test it and then I'll post the results here. :)
However, any prettier solution is most than welcome!