Hello,
I have encountered bug in ruby threads.
It can be demonstrated by following script:
----simplebug.rb--------------------------
require 'socket'
PORT=8080
def handle_client(sock)
5.times{ sock.write(sock.readline) } # echo few lines
sock.close
end
trap('HUP') {
puts 'Got SIGHUP'
}
server = TCPserver.open(PORT)
while true do
sock = server.accept
puts 'client accepted'
Thread.start do
handle_client(sock)
end
end
------------------------------------------
Run script, run telnet session to talk with it.
Send SIGHUP signal to script.
Now ruby is doing blocking accept call (instead of select
which is required for ruby threads to work).
Test on telnet session that no more lines are echoed back.
If you initiate another new telnet session, blocking accept
will stop blocking and things will continue to work correctly
(till next SIGHUP signal).
This bug applies to following ruby versions:
ruby 1.6.7 (2002-05-10) [i686-linux]
ruby 1.6.7 (2002-03-19) [i386-linux]
I have been searching the BUG for a few hours.
First obvious BUG:
----part of file eval.c---------------------
n = select(max+1, &readfds, &writefds, &exceptfds, delay_ptr);
if (n < 0) {
if (rb_trap_pending) rb_trap_exec();
if (errno == EINTR) goto again;
#ifdef ERESTART
if (errno == ERESTART) goto again;
#endif
---------------------------------------------
If rb_trap_exec is executed, errno is no longer valid
simple fix:
---------------------------------------------
n = select(max+1, &readfds, &writefds, &exceptfds, delay_ptr);
if (n < 0) {
int tmperrno=errno;
if (rb_trap_pending) rb_trap_exec();
if (tmperrno == EINTR) goto again;
#ifdef ERESTART
if (tmperrno == ERESTART) goto again;
#endif
---------------------------------------------
However this does not solve problem in the script above.
Problem is probably in thread switching somewhere.
call tree for rb_trap_exec
rb_trap_exec:
call signal_exec
rb_signal_exec:
call rb_thread_trap_eval
rb_thread_trap_eval: call rb_thread_ready
rb_thread_trap_eval: call rb_thread_restore_context
...
I currently don't have much time to dig in ruby source due to
school work.
Jakub Travnik
jabber://jtra / jabber.com
You can contact me also at irc.openprojects.net #ruby-lang