From: Jakub Travnik Date: 2002-05-15T02:29:43+09:00 Subject: [BUG] thread failure after trap 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