From: Brian Candler Date: 2002-11-12T03:48:24+09:00 Subject: Threading in I/O libraries I'd like to ask: how integrated is threading in Ruby's I/O libraries? In particular, (1) if I do a read from a socket, will Ruby call select() first to ensure that there is data available (to prevent blocking), or do I have to do that myself? (2) if I call select() in one thread and no data is available, will this block the whole Ruby interpreter? Or is it clever: combining all the select()s from multiple threads and waking them up as their FDs become ready? The reason I ask is because I'm thinking of playing with writing a proxy RADIUS server in Ruby using one of the RADIUS libraries out there. When forwarding a request, the thread will need to wait for a response before answering - and if I do a recvfrom() I don't want the whole interpreter to block :-) I've had a quick play with TCPServer and it appears to handle threading correctly - see below - but as there's no UDPServer it looks like I'll have to get a bit more into the nuts and bolts. BTW what's the easiest way to tidy up my Testserver below to remove all those @session.s? If I subclass TCPSocket [the class which server.accept returns] I still have somehow to convert the object returned by 'accept' to this new class. I'm sure there's an obvious Ruby Way to do this :-) Regards, Brian. #!/usr/local/bin/ruby -w class Testserver def initialize(session) @session = session end def run @session.print "+OK I am a fake POP3 server\n" while line = @session.gets case line when /quit/i break else @session.print "-ERR I don't understand #{line}" end end @session.print "+OK bye\n" @session.close end end require 'socket' port = (ARGV[0] || 110).to_i server = TCPServer.new('localhost', port) while (session = server.accept) Thread.new do Testserver.new(session).run end end