(unknown)

I've got a simple class that writes to a device on a serial port and then
reads back a response:

class SerialPort
  def write(port, arry)
    file = File.new(port, File::RDWR | File::NOCTTY )
    file.write(arry.pack("C*"))
    file.flush
    str = file.read(50).to_s.unpack("C*")
    file.close
    str
  end
end

(Usage: response = SerialPort.new.write("/dev/tts/5",
[some_array_of_bytes]) )

The class works fine for my program, until I go multi-threaded, which is a
requirement.

As soon as I do something this:

Thread.new do
  response = SerialPort.new.write("/dev/tts/5, [some_array_of_bytes])
end

The thread hangs at the read() function. If I use the same code in the
main thread it works fine. I thought at first I had resources that were
conflicting, but I've written a test case which does nothing other than
one call like seen above, and the only difference in working/not-working
is whether the code is invoked in a new thread or not.

Any thoughts on what I might be missing here? The serial port is set to
raw mode, min 0 time 1, which means that it won't block on reads even if
no data is present.

Caleb,

This message showed up under another, thread perhaps you replied to a message and just changed the subject heading. This makes it difficult for certain mail clients and newsreaders to correctly organize the mail in threads, next time could you compose a new email messsage to "ruby-talk@ruby-lang.org", that way more people will see your email, otherwise people may ignore the thread that this messages shows up under.

thx,

Zach

Caleb Tennis wrote:

···

I've got a simple class that writes to a device on a serial port and then
reads back a response:

class SerialPort
  def write(port, arry)
    file = File.new(port, File::RDWR | File::NOCTTY )
    file.write(arry.pack("C*"))
    file.flush
    str = file.read(50).to_s.unpack("C*")
    file.close
    str
  end
end

(Usage: response = SerialPort.new.write("/dev/tts/5",
[some_array_of_bytes]) )

The class works fine for my program, until I go multi-threaded, which is a
requirement.

As soon as I do something this:

Thread.new do
  response = SerialPort.new.write("/dev/tts/5, [some_array_of_bytes])
end

The thread hangs at the read() function. If I use the same code in the
main thread it works fine. I thought at first I had resources that were
conflicting, but I've written a test case which does nothing other than
one call like seen above, and the only difference in working/not-working
is whether the code is invoked in a new thread or not.

Any thoughts on what I might be missing here? The serial port is set to
raw mode, min 0 time 1, which means that it won't block on reads even if
no data is present.

Excerpts from Caleb Tennis's mail of 7 Feb 2005 (EST):

As soon as I do something this:

Thread.new do
  response = SerialPort.new.write("/dev/tts/5, [some_array_of_bytes])
end

The thread hangs at the read() function. If I use the same code in the
main thread it works fine.

This might be related to [ruby-talk:109668] [ruby-talk:125125], in which
Ruby's switch to select() over read() in the presence of Threads can
cause freezes under kernel 2.6. But maybe not; the behavior there is
slightly different.

Can you post an strace?

···

--
William <wmorgan-ruby-talk@masanjin.net>

I posted an strace under [ruby-talk:130019], and it shows that indeed select()
is being used in the thread and is causing the hang.

I've been able to work around the problem by switching to sysread() and
syswrite() in my class.

Thanks,
Caleb

···

On Monday 07 February 2005 22:27, William Morgan wrote:

This might be related to [ruby-talk:109668] [ruby-talk:125125], in which
Ruby's switch to select() over read() in the presence of Threads can
cause freezes under kernel 2.6. But maybe not; the behavior there is
slightly different.

Can you post an strace?

Excerpts from Caleb Tennis's mail of 8 Feb 2005 (EST):

I posted an strace under [ruby-talk:130019], and it shows that indeed
select() is being used in the thread and is causing the hang.

I've been able to work around the problem by switching to sysread()
and syswrite() in my class.

Interesting. In my experiments with files on /proc, sysread() still
results in a hanging select() system call. Wonder why it works for you.

···

--
William <wmorgan-ruby-talk@masanjin.net>