I’ve been experimenting with a Ruby web server called httpd.rb
(from http://www.xs4all.nl/~hipster/) on Windows XP.
httpd.rb uses a master/worker thread model. A master thread keeps
accepting incoming TCP connections and pushes them onto a queue (some
code omitted for brevity):
loop do; @rqueue.push @socket.accept; end
where @socket.is_a?(TCPServer). Meanwhile, the worker threads do this:
loop do
socket = @rqueue.pop
<read the HTTP request from socket and write the response>
end
where socket.is_a?(TCPSocket).
When I benchmarked httpd.rb using the “ab” command (Apache benchmark)
doing 1000 requests with 100 concurrency, it froze up. All the worker
threads were stuck running TCPSocket#gets, and didn’t know that the
client had already disconnected. (If I do the same thing on Linux, it
will raise a broken pipe exception, thus breaking the loop.)
Does anyone have any ideas as to how I can make it not get stuck on
WinXP? It seems the problem is that TCPSocket#gets may block forever
instead of raising SIGPIPE if the other side has disappeared.