# Issue with threads and socket accept

**URL:** <https://www.ruby-forum.com/t/issue-with-threads-and-socket-accept/122883>\
**Category:** Ruby\
**Created:** [December 12, 2007, 7:11pm UTC](https://www.ruby-forum.com/t/issue-with-threads-and-socket-accept/122883 "2007-12-12T19:11:39Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Vasyl\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@Vasyl\_S](https://www.ruby-forum.com/u/Vasyl_S)\
**Post date:** [December 12, 2007, 7:11pm UTC](https://www.ruby-forum.com/t/issue-with-threads-and-socket-accept/122883/1 "2007-12-12T19:11:39Z")

</div>

Hi,

I’m writing a multi-threaded server, and would like to stop it on a  
signal (SIGINT on Ctrl-C in this case).  
The problem is that after the first connection is accepted, and then  
Ctrl-C is hit, the “while accept” loop doesn’t break. If you hit Ctrl-  
C before any connections, it just works fine. And the single-threaded  
version, of course, works  
as well.

Could somebody explain what am I doing wrong?

Below is a simple application that reproduces the problem. Change the  
last line to “server.serve\_seq” to run a single-threaded version.

Thanks in advance!

#!/usr/local/bin/ruby -w

require ‘socket’

class MyServer  
def initialize  
@servsock = TCPServer.new(“127.0.0.1”, 1111)  
end

def work(sock)  
begin  
lines = 0  
lines += 1 while sock.gets  
puts “Got #{lines} lines.”  
rescue Exception =\> e  
print "exception: "; p e  
ensure  
sock.close  
end  
end

def serve\_mt  
while clisock = @servsock.accept  
Thread.new(clisock) { |sock| work(sock) }  
end  
end

def serve\_seq  
while sock = @servsock.accept  
work(sock)  
end  
end

def shutdown  
return nil if @servsock.nil? or @servsock.closed?  
puts “Shutting down…”  
@servsock.close  
end  
end

server = MyServer.new  
Signal.trap(“INT”) { server.shutdown }  
server.serve\_mt

---

<div class="post-metadata">

**Author:** ![Vasyl\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@Vasyl\_S](https://www.ruby-forum.com/u/Vasyl_S)\
**Post date:** [December 12, 2007, 7:21pm UTC](https://www.ruby-forum.com/t/issue-with-threads-and-socket-accept/122883/2 "2007-12-12T19:21:10Z")

</div>

On Dec 11, 2007 11:18 AM, Vasyl S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Could somebody explain what am I doing wrong?

Without addressing your specific question, let me suggest that you  
investigate the Ruby/Eventmachine library. It should make your  
application  
easier to develop.

---

<div class="post-metadata">

**Author:** ![Vasyl\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@Vasyl\_S](https://www.ruby-forum.com/u/Vasyl_S)\
**Post date:** [December 12, 2007, 7:24pm UTC](https://www.ruby-forum.com/t/issue-with-threads-and-socket-accept/122883/3 "2007-12-12T19:24:09Z")

</div>

On Dec 11, 7:53 pm, “Francis C.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Without addressing your specific question, let me suggest that you  
> investigate the Ruby/Eventmachine library. It should make your application  
> easier to develop.

Thanks, Francis, I’m just reading the docs for your library!

---

<div class="post-metadata">

**Author:** ![Vasyl\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@Vasyl\_S](https://www.ruby-forum.com/u/Vasyl_S)\
**Post date:** [December 12, 2007, 7:25pm UTC](https://www.ruby-forum.com/t/issue-with-threads-and-socket-accept/122883/4 "2007-12-12T19:25:59Z")

</div>

On 2007-12-12 01:18 +0900 (Wed), Vasyl S. wrote:

> I’m writing a multi-threaded server, and would like to stop it on a  
> signal (SIGINT on Ctrl-C in this case).  
> The problem is that after the first connection is accepted, and then  
> Ctrl-C is hit, the “while accept” loop doesn’t break…  
> Could somebody explain what am I doing wrong?

Errr…“not investigating deep and strange mysteries of the Ruby  
interpreter  
signal handling that are not comprehensible even after reading the  
source?”

I hope I get a point for that answer.

But anyway, much as I’d like to know _why_ the signal handling is set up  
to ignore signals when waiting in accept(), a situation on which the  
source code that does this is particularly silent, I just live with the  
solution, which is:

Do a select() before your accept(), and wait until the socket in  
question becomes readable.

You and I are not the only ones caught by this, as it happens. The  
native  
Ruby FastCGI code has the same issue.

cjs

---

<div class="post-metadata">

**Author:** ![Vasyl\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@Vasyl\_S](https://www.ruby-forum.com/u/Vasyl_S)\
**Post date:** [December 12, 2007, 7:26pm UTC](https://www.ruby-forum.com/t/issue-with-threads-and-socket-accept/122883/5 "2007-12-12T19:26:38Z")

</div>

On Dec 11, 7:43 pm, Curt S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Errr…“not investigating deep and strange mysteries of the Ruby interpreter  
> signal handling that are not comprehensible even after reading the source?”
> 
> I hope I get a point for that answer.

You probably do 🙂

> But anyway, much as I’d like to know _why_ the signal handling is set up  
> to ignore signals when waiting in accept(), a situation on which the  
> source code that does this is particularly silent, I just live with the  
> solution, which is:

Well, actually the signal handler gets called, it calls shutdown,  
outputs a message  
to the stdout and closes the server socket. And the main thread is  
still inside accept.

> Do a select() before your accept(), and wait until the socket in  
> question becomes readable.

I’ve tried this, with the same success:

def serve\_mt2  
until @servsock.closed?  
IO.select([@servsock])  
clisock = @servsock.accept  
Thread.new(clisock) { |sock| work(sock) }  
end  
end
