[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Issue with threads and socket accept

Vasyl Smirnov

12/11/2007 4:18:00 PM

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

5 Answers

Curt Sampson

12/11/2007 5:44:00 PM

0

On 2007-12-12 01:18 +0900 (Wed), Vasyl Smirnov 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
--
Curt Sampson <cjs@starling-software.com> +81 90 7737 2974
Mobile sites and software consulting: http://www.starling-so...

Francis Cianfrocca

12/11/2007 5:54:00 PM

0

Note: parts of this message were removed by the gateway to make it a legal Usenet post.

On Dec 11, 2007 11:18 AM, Vasyl Smirnov <vasyl.smirnov@gmail.com> wrote:

> 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?
>


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

Vasyl Smirnov

12/11/2007 6:25:00 PM

0



On Dec 11, 7:53 pm, "Francis Cianfrocca" <garbageca...@gmail.com>
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!

Vasyl Smirnov

12/11/2007 6:27:00 PM

0



On Dec 11, 7:43 pm, Curt Sampson <c...@cynic.net> 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

Robin

6/5/2008 3:08:00 PM

0

On Jun 5, 8:09 am, "Pieter" <hrdou...@zonnet.nl> wrote:
> "MikeRyder" <n...@nospam.com> schreef in berichtnews:o07e44dnsms3hfqvuon2icfrh1ehrorqot@4ax.com...
>
> > On Wed, 4 Jun 2008 15:39:39 -0700 (PDT), george
> > <georgeculol...@hotmail.com> wrote:
> >>I can choose to see the sinlessness of everyone.
>
> > How about their actions.
>
> > Back to ol' Hitler again. Or...how about bin laden. How do you
> > perceive his actions?
>
> Jesus speaks in the Course of
> "appalling errors", and says of the
> perpetrators: "Father, forgive them
> for they know not what they do."
> Moreover, he says that we are not
> guiltless in time, but in eternity.
>
> "Time seems to go in one direction, but when you
> reach its end, it will roll up like a long carpet that
> has spread along the past behind you, and will
> disappear. As long as you believe the Son of God
> is guilty, you will walk along this carpet, believing
> that it leads to death. And the journey will seem
> long and cruel and senseless, for so it is." (1800; T-13.I.5:5-7)

Yes Bush just as crazy as bin laden, but he has the people of American
to make his atrocities ok...