# GServer in Ruby 2.0.0

**URL:** <https://www.ruby-forum.com/t/gserver-in-ruby-2-0-0/225347>\
**Category:** Ruby\
**Created:** [January 1, 2013, 5:21pm UTC](https://www.ruby-forum.com/t/gserver-in-ruby-2-0-0/225347 "2013-01-01T17:21:20Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![aris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@aris](https://www.ruby-forum.com/u/aris)\
**Post date:** [January 1, 2013, 5:21pm UTC](https://www.ruby-forum.com/t/gserver-in-ruby-2-0-0/225347/1 "2013-01-01T17:21:20Z")

</div>

I’m working on updating a gem to be compatible with Ruby 2.0 and am  
currently using Ruby 2.0.0-preview2. I’m running into trouble with a  
class which inherits from GServer and I think it’s related to this bug  
and subsequent patch [https://bugs.ruby-lang.org/issues/6416](https://bugs.ruby-lang.org/issues/6416). Please  
look at the gist:[SIGINT causes an exception when executing with Ruby 2.0 but not with Ruby 1.9.3. · GitHub](https://gist.github.com/4424479)

Using Ruby \<= 1.9.3, when sending an interrupt signal this code would  
exit cleanly. Using Ruby 2.0, an exception is thrown on launcher.stop:

~/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/2.0.0/gserver.rb:116:in  
`synchronize': can't be called from trap context (ThreadError) from ~/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/2.0.0/gserver.rb:116:in `stop’

As you can see, I am not explicitly calling ‘join’ in the trap context  
but ‘synchronize’ is called as part of GServer#close

gserver.rb  
114 # Stop the server  
115 def stop  
116 @connectionsMutex.synchronize {  
117 if @tcpServerThread  
118 @tcpServerThread.raise “stop”  
119 end  
120 }  
121 end

I’m open to any ideas or suggestions. Thanks!

---

<div class="post-metadata">

**Author:** ![ldt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/c0e974/32.png) [@ldt](https://www.ruby-forum.com/u/ldt)\
**Post date:** [January 4, 2013, 2:45pm UTC](https://www.ruby-forum.com/t/gserver-in-ruby-2-0-0/225347/2 "2013-01-04T14:45:04Z")

</div>

On Tue, Jan 1, 2013 at 4:20 PM, Joe L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> `synchronize': can't be called from trap context (ThreadError) from ~/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/2.0.0/gserver.rb:116:in `stop’

I can confirm this is new behaviour in 2.0.0-preview2 - it also  
happens when you use Queue#enq from within a trap handler (which is an  
issue for me unfortunately).

You could use a variant of the self-pipe trick to signal a thread as  
in the example below. Regards, Sean.

# CODE

require “gserver”

# example server

class MyServer \< GServer  
def initialize(port=10001, \*args)  
super(port, \*args)  
end  
def serve(io)  
io.puts(Time.now.to\_s)  
end  
end

class Launcher  
def initialize(servers)  
@servers = servers  
end

def start  
@servers.each { |server| server.start }  
end

def join  
@servers.each { |server| server.join }  
end

def stop  
@servers.each { |server| server.stop }  
end  
end

servers = [MyServer.new]  
launcher = Launcher.new(servers)

# create self-pipe

p\_read, p\_write = IO.pipe

Thread.start(launcher, p\_read) do |l, pr|  
pr.read # blocks until write end closed  
pr.close  
l.stop  
exit  
end

launcher.start  
trap(“SIGINT”) { p\_write.close } # close pipe to signal thread  
launcher.join

---

<div class="post-metadata">

**Author:** ![ldt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/c0e974/32.png) [@ldt](https://www.ruby-forum.com/u/ldt)\
**Post date:** [January 5, 2013, 1:51am UTC](https://www.ruby-forum.com/t/gserver-in-ruby-2-0-0/225347/3 "2013-01-05T01:51:17Z")

</div>

Wow, this is a really interesting (and effective) solution. Reading the  
docs on IO.pipe ([Class: IO (Ruby 1.9.3)](http://www.ruby-doc.org/core-1.9.3/IO.html)) this looks  
pretty safe. And it works on Ruby 1.9.3 and 2.0.0-preview2.

My objective was to clean up my resources when the program receives a  
SIGTERM. (As a counter example, calling “exit!” inside the original trap  
context in my gist would have successfully killed my program without  
throwing an exception but would not have cleaned up the utilized  
resources.) There is the ominous “does not work on all systems” warning  
with this method, but if I can test it out on some of the major ones  
successfully, I’ll go with it.

For what it’s worth, I’ve filed my issue with ruby-core here:  
[Bug #7648: GServer does not close cleanly from signal interrupt context - Ruby master - Ruby Issue Tracking System](http://bugs.ruby-lang.org/issues/7648). It hasn’t gained any traction  
yet,  
but if you want to post your own experience with Queue#enq it might be  
an  
addendum to this bug report or a new bug altogether.

Thanks for your help! This was educational.

Joe
