(I posted this a little earlier, but apparently it got sent with no
subject and was hidden within another thread - mail reader mishap I
suppose - my apologies for posting again):

A small testcase program has unexpected results:

-------

require 'thread'
$serport = "/dev/tts/5"

class SerialPort
  def write(port, arry)
    puts "WRITING: #{arry.inspect}"
    file = File.new(port, File::RDWR | File::NOCTTY )
    puts "WRITE"
    file.write(arry.pack("C*"))
    puts "READ"
    str = file.read(50).to_s.unpack("C*")
    puts "CLOSE"
    file.close
    puts "READ: #{str.inspect}"
    str
  end
end

a = Thread.new do
  SerialPort.new.write($serport, [ 4, 4, 0, 16, 0, 1, 48, 90]);
end

a.join

------

The program hangs on the read() call - if I run the same program above and
perform the "SerialPort.new.write()" call without making a new thread, the
code works fine.  I performed an strace, with some interesting results -
namely, that for the multithreaded application I don't ever see a call to
the system's read/write, just select.  The above code works fine for
regular files - it just seems to have trouble with device files.

Is this a bug or am I just missing something?



As a single thread:
-------
open("/dev/tts/5", O_RDWR|O_NOCTTY|O_LARGEFILE) = 3
fcntl64(3, F_GETFL)                     = 0x8002 (flags O_RDWR|O_LARGEFILE)
fstat64(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(4, 69), ...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B19200 -opost -isig -icanon -echo
...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
= 0x40014000
_llseek(3, 0, 0xbfffd580, SEEK_CUR)     = -1 ESPIPE (Illegal seek)
write(1, "WRITE\n", 6WRITE
)                  = 6
write(1, "READ\n", 5READ
)                   = 5
write(3, "\4\4\0\20\0\0010Z", 8)        = 8
read(3, "\4\4\2\0\0u0", 1024)           = 7
read(3, "", 1024)                       = 0
write(1, "CLOSE\n", 6CLOSE
)                  = 6
close(3)                                = 0
munmap(0x40014000, 4096)                = 0
write(1, "READ: [4, 4, 2, 0, 0, 117, 48]\n", 31READ: [4, 4, 2, 0, 0, 117, 48]
) = 31
munmap(0x40013000, 4096)                = 0
_exit(0)                                = ?
-------------

As two threads:
------------------
open("/dev/tts/5", O_RDWR|O_NOCTTY|O_LARGEFILE) = 3
fcntl64(3, F_GETFL)                     = 0x8002 (flags O_RDWR|O_LARGEFILE)
fstat64(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(4, 69), ...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B19200 -opost -isig -icanon -echo
...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
= 0x40014000
_llseek(3, 0, 0xbfffba40, SEEK_CUR)     = -1 ESPIPE (Illegal seek)
write(1, "WRITE\n", 6WRITE
)                  = 6
write(1, "READ\n", 5READ
)                   = 5
select(4, [3], [], [], {0, 0})          = 0 (Timeout)
brk(0)                                  = 0x808d000
brk(0x8091000)                          = 0x8091000
gettimeofday({1107792091, 536853}, NULL) = 0
select(4, [3], [], [], NULL <unfinished ...>
--------------