Caleb Tennis
2/7/2005 4:20:00 PM
(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 ...>
--------------