On Mon, 5 Sep 2005, Bill Kelly wrote: > From: "Bill Kelly" <billk / cts.com> > >>>> require 'socket' >> => true >>>> require 'thread' >> => true >>>> cl = TCPSocket.new("localhost", 12345) >> => #<TCPSocket:0x2dbaf88> >>>> th1 = Thread.new { sleep(1.0) until cl.eof? } >> => #<Thread:0x2db6dd0 sleep> >>>> th2 = Thread.new { sleep(1.0) until cl.eof? } >> => #<Thread:0x2db2bb8 sleep> >>>> cl.eof? >> >> ^^^^^^^^ hang > > > I guess it must be something very basic I'm not aware of > about #eof? ... Because even: > >>>> require 'socket' >> => true >>>> require 'thread' >> => true >>>> cl = TCPSocket.new("localhost", 12345) >> => #<TCPSocket:0x2dbaf88> >>>> cl.eof? > > hangs. > > > Is it not possible to check for EOF without blocking? sometimes yes, sometimes no, or so it seems: [ahoward@localhost ~]$ cat a.rb require 'socket' s = TCPSocket::new '127.0.0.1', 80 s.eof? [ahoward@localhost ~]$ strace ruby a.rb 2>&1 ... ... ... read(3 and, from io.c: /* * call-seq: * ios.eof => true or false * ios.eof? => true or false * * Returns true if <em>ios</em> is at end of file. The stream must be * opened for reading or an <code>IOError</code> will be raised. * * f = File.new("testfile") * dummy = f.readlines * f.eof #=> true */ VALUE rb_io_eof(io) VALUE io; { OpenFile *fptr; int ch; GetOpenFile(io, fptr); rb_io_check_readable(fptr); if (feof(fptr->f)) return Qtrue; if (READ_DATA_PENDING(fptr->f)) return Qfalse; READ_CHECK(fptr->f); clearerr(fptr->f); TRAP_BEG; ch = getc(fptr->f); // look here !!! TRAP_END; if (ch != EOF) { ungetc(ch, fptr->f); return Qfalse; } rb_io_check_closed(fptr); clearerr(fptr->f); return Qtrue; } i'm no systems/network guy - but it seems like maybe one shouldn't try to read a char from anything like a socket, pipe, etc. that might hang for a read in this case... i dunno how to check for this kind of thing though... maybe: if(fseek(fptr->f) == EBADF) { return Qnil; // we can't tell for this stream! } else { TRAP_BEG; ch = getc(fptr->f); TRAP_END; } or maybe an error could be thrown up front for this case (Errno::EWOULDBLOCK for example)... but this doesn't seem right since you may want to check eof for a socket at times... nil could mean "don't know." anyhow... it sure makes sense that it'd block though... hth. -a -- =============================================================================== | email :: ara [dot] t [dot] howard [at] noaa [dot] gov | phone :: 303.497.6469 | Your life dwells amoung the causes of death | Like a lamp standing in a strong breeze. --Nagarjuna ===============================================================================