# Breaking Out Of A Loop

**URL:** <https://www.ruby-forum.com/t/breaking-out-of-a-loop/54320>\
**Category:** Ruby\
**Created:** [March 1, 2006, 3:05pm UTC](https://www.ruby-forum.com/t/breaking-out-of-a-loop/54320 "2006-03-01T15:05:27Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![mike](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58f4c7/32.png) [@mike](https://www.ruby-forum.com/u/mike)\
**Post date:** [March 1, 2006, 3:05pm UTC](https://www.ruby-forum.com/t/breaking-out-of-a-loop/54320/1 "2006-03-01T15:05:27Z")

</div>

I’m somewhat new to Ruby and have been playing around with some very  
simple  
socket code (starting the script and then telnetting to the box on the  
port  
specified). I wanted to allow it to accept more than one request at a  
time  
so I added some threads. However, now that I’ve added some thread code,  
I  
can’t get the script to end properly (I guess “as expected” is more  
appropriate). Here’s some code:

require ‘socket’  
p = 3333  
threads = []  
s = ‘’

server = TCPServer.new(‘0.0.0.0’, p)

while (session = server.accept)  
threads \<\< Thread.new(session) do |ts|  
ts.print “What’s your name?\r\n”  
puts “Request: #{s = ts.gets.chomp!}”  
ts.print “\r\nHello #{s}, thanks for stopping by\r\n\r\n”  
ts.close  
end  
break if s == ‘close’  
end

How it behaves is that if you connect and then send the string ‘close’,  
it  
accepts it and handles it as a normal request with any other string.  
However, on the connection following the one with ‘close’, it will then  
terminate the script. I’m of the impression that it _should_ close it as  
soon as I send ‘close’, but this is obviously not the case. Without the  
threading, it was working fine:

require ‘socket’  
p = 2222  
server = TCPServer.new(‘0.0.0.0’, p)

while (session = server.accept)  
session.print “What’s your name?\r\n”  
puts “Request: #{s = session.gets.chomp!}”  
session.print “\r\nHello #{s}, thanks for stopping by\r\n\r\n”  
session.close  
if s == ‘close’  
break  
end  
End

This obviously needed to be modified some since the break would be  
inside of  
the thread block and wouldn’t terminate the while loop. That’s  
ultimately  
why I’m defining s outside of the loop so that the threads have access  
to it  
and can use it as an ugly global that I was hoping would be read and  
used to  
close the while loop as the thread goes to it’s ‘end’.

Any insight would be appreciated - pardon the ugly code, this is my  
first  
real foray into sockets, threads and ruby 🙂

---

<div class="post-metadata">

**Author:** ![mike](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58f4c7/32.png) [@mike](https://www.ruby-forum.com/u/mike)\
**Post date:** [March 1, 2006, 4:16pm UTC](https://www.ruby-forum.com/t/breaking-out-of-a-loop/54320/2 "2006-03-01T16:16:35Z")

</div>

On Wed, Mar 01, 2006 at 11:04:31PM +0900, Mike wrote:

> while (session = server.accept)  
> threads \<\< Thread.new(session) do |ts|  
> ts.print “What’s your name?\r\n”  
> puts “Request: #{s = ts.gets.chomp!}”  
> ts.print “\r\nHello #{s}, thanks for stopping by\r\n\r\n”  
> ts.close  
> end  
> break if s == ‘close’  
> end

You have a race condition. “s == ‘close’” is getting evaluated before  
“s = ts.gets.chomp!”. That’s why the program doesn’t exit until the  
next time through the loop.

In this solution, the child thread causes the main thread to raise an  
exception, breaking out of the accept() call:

require ‘socket’  
p = 3333  
server = TCPServer.new(‘0.0.0.0’, p)

loop do  
begin  
Thread.new(server.accept) do |ts|  
ts.print “What’s your name?\r\n”  
puts “Request: #{s = ts.gets.chomp!}”  
if s == ‘close’  
Thread.main.raise “Closing”  
else  
ts.print “\r\nHello #{s}, thanks for stopping by\r\n\r\n”  
end  
ts.close  
end  
rescue  
puts “Exiting”  
break  
end  
end

regards,  
Ed
